性能
OpenTelemetry Java 代理通过在相同的 Java 虚拟机 (JVM) 中运行来仪表您的应用程序。与任何其他软件代理一样,Java 代理需要 CPU、内存和网络带宽等系统资源。代理的资源使用称为代理开销或性能开销。OpenTelemetry Java 代理在仪表 JVM 应用程序时对系统性能的影响很小,尽管最终的代理开销取决于多个因素。
可能增加代理开销的因素包括环境因素,例如物理机器架构、CPU 频率、内存量和速度、系统温度以及资源争用。其他因素包括虚拟化和容器化、操作系统及其库、JVM 版本和供应商、JVM 设置、被监控软件的算法设计以及软件依赖项。
由于现代软件的复杂性和部署场景的多样性,无法给出一个单一的代理开销估算值。要找到给定部署中任何仪表代理的开销,您必须进行实验并直接收集测量结果。因此,请将所有关于性能的陈述视为一般信息和指南,这些指南可能会在特定系统上进行评估。
以下章节描述了 OpenTelemetry Java 代理的最低要求、可能影响性能的限制因素以及优化和排查代理性能的指南。
减少代理开销的指南
以下最佳实践和技术可能有助于减少 Java 代理引起的开销。
配置跟踪采样
仪表处理的 Span 的数量可能会影响代理开销。您可以配置跟踪采样来调整 Span 的数量并减少资源使用。请参阅 采样。
关闭特定的仪表
您可以通过关闭不需要或产生过多 Span 的仪表来进一步减少代理开销。要关闭仪表,请使用 -Dotel.instrumentation.<name>.enabled=false 或 OTEL_INSTRUMENTATION_<NAME>_ENABLED 环境变量,其中 <name> 是仪表的名称。
例如,以下选项关闭了 JDBC 仪表:-Dotel.instrumentation.jdbc.enabled=false
为应用程序分配更多内存
使用 -Xmx<size> 选项增加 JVM 的最大堆大小可能有助于缓解代理开销问题,因为仪表会生成大量短暂的对象在内存中。
将手动仪表减少到您需要的程度
过多的手动仪表可能会引入低效率,从而增加代理开销。例如,在每个方法上使用 @WithSpan 会导致 Span 量很高,进而增加数据中的噪声并消耗更多系统资源。
提供充足的资源
确保为您的仪表和 Collector 提供足够的资源。内存或磁盘等资源的数量取决于您的应用程序架构和需求。例如,常见的设置是在运行 OpenTelemetry Collector 的同一台主机上运行已仪表化的应用程序。在这种情况下,请考虑调整 Collector 的资源大小并优化其设置。请参阅 扩展。
影响 Java 代理性能的限制因素
通常,您从应用程序收集的遥测数据越多,对代理开销的影响就越大。例如,跟踪与您的应用程序无关的方法仍然会产生相当大的代理开销,因为跟踪这些方法在计算上比运行方法本身更昂贵。同样,高基数(cardinality)的标签在指标中可能会增加内存使用量。如果开启调试日志,也会增加到磁盘的写操作和内存使用量。
某些仪表,例如 JDBC 或 Redis,会产生大量的 Span,从而增加代理开销。有关如何关闭不必要的仪表的更多信息,请参阅 关闭特定的仪表。
Java 代理的实验性功能可能会增加代理开销,因为实验性功能侧重于功能而非性能。在代理开销方面,稳定功能更安全。
排查代理开销问题
在排查代理开销问题时,请执行以下操作
- 检查最低要求。请参阅 先决条件。
- 使用最新兼容版本的 Java 代理。
- 使用最新兼容版本的 JVM。
考虑采取以下措施来降低代理开销
- 如果您的应用程序接近内存限制,请考虑为其提供更多内存。
- 如果您的应用程序占用了所有 CPU,您可能需要对其进行水平扩展。
- 尝试关闭或调整指标。
- 调整跟踪采样设置以减少 Span 的数量。
- 关闭特定的仪表。
- 审查手动仪表以避免不必要的 Span 生成。
衡量代理开销的指南
在您自己的环境和部署中衡量代理开销,可以提供关于仪表对应用程序或服务性能影响的准确数据。以下指南描述了收集和比较可靠的代理开销测量结果的通用步骤。
确定您要衡量的内容
您的应用程序或服务的不同用户可能会注意到代理开销的不同方面。例如,虽然最终用户可能会注意到服务延迟的下降,但具有重度工作负载的重度用户更关注 CPU 开销。另一方面,经常部署的用户(例如由于弹性工作负载)更关心启动时间。
将您的测量限制在一定会影响用户体验的因素上,这样您的数据集就不会包含无关信息。一些测量示例包括以下内容:
- 用户平均 CPU 使用率、用户峰值 CPU 使用率和机器平均 CPU 使用率
- 分配的总内存和最大堆使用量
- 垃圾回收暂停时间
- 毫秒为单位的启动时间
- 平均和 95 百分位 (p95) 服务延迟
- 网络读写平均吞吐量
准备合适的测试环境
通过在受控的测试环境中测量代理开销,您可以更好地识别影响性能的因素。准备测试环境时,请完成以下步骤:
- 确保测试环境的配置与生产环境相似。
- 将待测应用程序与其他可能干扰的服务隔离开来。
- 关闭或删除应用程序主机上所有不必要的系统服务。
- 确保应用程序有足够的系统资源来处理测试工作负载。
创建一套真实的测试
设计您在测试环境中运行的测试,使其尽可能地模拟典型工作负载。例如,如果您的服务的某些 REST API 端点容易受到高请求量的影响,则创建一个模拟大量网络流量的测试。
对于 Java 应用程序,在开始测量之前使用预热阶段。JVM 是一个高度动态的机器,通过即时编译 (JIT) 执行大量优化。预热阶段有助于应用程序完成大部分类加载,并为 JIT 编译器提供时间来执行大部分优化。
确保运行大量请求并多次重复测试。这种重复有助于确保代表性的数据样本。在您的测试数据中包含错误场景。模拟与正常工作负载相似的错误率,通常在 2% 到 10% 之间。
定向到可观察性后端和其他商业服务时,测试可能会增加成本。请相应地规划您的测试,或考虑使用替代解决方案,例如自托管或本地运行的后端。
收集可比较的测量结果
为了确定哪些因素可能影响性能并导致代理开销,请在修改单个因素或条件后,在相同的环境中收集测量结果。
分析代理开销数据
收集多次运行数据后,您可以将结果绘制在图表中,或使用统计检验比较平均值以检查是否存在显著差异。
请注意,不同的技术栈、应用程序和环境可能导致不同的操作特性和不同的代理开销测量结果。