OpenResty XRay 是一款 Java 应用性能剖析工具,它使用动态追踪技术代替 JVM agent,来剖析生产环境中的 CPU 热点、Off-CPU 阻塞和磁盘 I/O。由于不依赖 JVM 的 safepoint 机制,XRay 避免了传统 Java 采样分析器常见的 safepoint 偏差,能够提供更准确、更全面的性能数据。它可以在不做任何修改的 OpenJDK 8/11/17/21 上运行,覆盖从现代 Linux 发行版到 RHEL/CentOS 7(3.10 内核)等老系统。

在底层实现上,XRay 由我们自主改进的动态追踪运行时驱动,例如 eBPF+ 和 Stap+。与基于 agent 的 Java 分析器相比,它具备以下优势:

  1. 零侵入:无需修改代码、无需改配置、无需 agent JAR 包,也无需 -javaagent 参数。
  2. 无 Safepoint 偏差:XRay 不依赖 JVM 的 safepoint 机制,因此其 CPU 火焰图比基于 agent 的采样分析器更准确。
  3. 广泛兼容:同时支持 OpenJDK 8、11、17、21,覆盖现代 Linux 与 CentOS 7 时代的 3.10 内核。
  4. 接近零开销:采样时开销可忽略不计,不采样时零开销。

在这篇文章中,我们将带你走过 OpenResty XRay 的三个 Java 应用剖析场景:CPU 热点分析、Off-CPU/锁等待分析,以及磁盘 I/O 剖析。如果你遇到的是内存问题,可以参考姊妹篇无需堆转储诊断生产环境 Java 内存泄漏

用火焰图剖析 Java CPU 热点

当 Java 应用的 CPU 使用率异常高时,通常意味着某些代码路径消耗了过多的计算资源。通过 OpenResty XRay引导式分析可以帮助您快速定位这些热点代码。

例如,这是由 OpenResty XRay 为一个压测状态下的 Java 应用(在这个例子中是 Tomcat HTTP 应用,但同样适用于任何未经修改的 Java 应用)生成的 CPU 火焰图:

在这个火焰图中,每个条形代表一个函数调用,条形的宽度表示该函数占用的 CPU 时间比例。条形越宽,表示该函数消耗的 CPU 时间越多。

仔细分析这张图,我们可以清晰地看到 Java 函数 sun.nio.ch.FileDispatcherImpl:write0 占据了最大的 CPU 时间份额。这是 Java 虚拟机内部使用的一个本地方法,主要用于将数据写入文件或网络套接字。这一发现与我们的压测场景高度吻合,因为在压测过程中,大量的 CPU 资源被用于返回响应数据。值得注意的是,OpenResty XRay 能够精确定位到具体的 .java 源文件和行号级别,让您能够直接找到性能热点的确切位置,大大提高了问题定位和优化的效率。

因为 OpenResty XRay 不依赖 JVM 的 safepoint 机制,这张 CPU 火焰图不存在困扰传统 Java 采样分析器的 safepoint 偏差

Java CPU 剖析器细节视图——火焰图中高亮显示的 .java 源文件与行号

基于这些深入的分析结果,您可以有的放矢地优化这些性能热点。可能的优化策略包括但不限于:改进算法效率、减少不必要的计算、引入适当的缓存机制,或者优化 I/O 操作等。通过这些有针对性的优化,您可以有效降低应用的 CPU 使用率,提升整体性能。

一旦火焰图定位到了热点方法,你还可以用非侵入式的 Java 函数探针实时抓取该方法的调用参数——无需 agent,无需字节码插桩,也无需重启。

Off-CPU Java 性能分析:锁等待与阻塞诊断

有时,Java 应用的 CPU 使用率上不去也可能是一个问题,通常是由 IO 阻塞、等待锁或其他资源竞争导致的。OpenResty XRay 可以帮助您找出这些瓶颈。

例如,这是由 OpenResty XRay 为一个低 CPU 使用率的 Java 应用生成的 off-CPU 火焰图:

在这个火焰图中,每个条形代表一个函数调用,条形的宽度表示该函数阻塞 CPU 的时间。条形越宽,表示该函数阻塞 CPU 的时间越多。

仔细观察火焰图中最宽的部分,我们可以发现在 BankSystem.java 的第 76 行调用了 java.util.concurrent.locks.ReentrantLock:lock 函数来获取锁。这里的宽矩形表明多个线程在等待这个锁,导致 CPU 使用率无法提高。

Off-CPU 火焰图细节视图——BankSystem.java 第 76 行的 ReentrantLock:lock 锁竞争

通过分析这些详细信息,您可以快速识别出导致 CPU 利用率低的根本原因。根据具体情况,您可以采取相应的优化措施,如改进锁策略、优化 IO 操作,或引入异步编程技术,从而全面提升应用的性能表现。

如果想从请求维度查看同样的阻塞行为,可以参考如何用逐请求 PCAP 精确定位那个慢 Tomcat 请求

Java 磁盘 I/O 剖析:从系统调用到 Java 源码行

硬盘 IO 过高不仅会显著影响应用性能,还可能导致整个系统运行缓慢。OpenResty XRay 是一款强大的工具,能够帮助您精确定位 Java 应用中引起高硬盘 IO 的代码路径。

下图展示了一个高硬盘 IO 场景下的 Java 应用火焰图:

仔细分析火焰图中最宽的部分,我们可以清晰地看到,在 SaveCache.java 文件的第 103 行调用的写入函数 java.io.Writer:write 是导致硬盘 IO 压力的主要来源。

磁盘 I/O 火焰图细节视图——SaveCache.java 第 103 行的 java.io.Writer:write

基于这些精确的信息,您可以有针对性地优化硬盘 IO 密集的代码。例如,可以考虑使用缓冲技术、实现异步 IO 操作,或采用批量处理等策略来有效降低硬盘 IO 压力,从而提升整体系统性能。

如果想从一次 write() 系统调用一路还原出完整调用栈、追溯到发起写入的业务方法,可以参考用时间穿梭调用栈调试 Java 文件 I/O

通过 OpenResty XRay 的深入分析,您可以更加高效地识别和解决性能瓶颈,确保您的 Java 应用在各种负载条件下都能保持卓越的性能表现。

支持 OpenJDK 8/11/17/21 应用剖析

OpenResty XRay 支持所有主流 OpenJDK 版本的 Java 应用剖析:

  • OpenJDK 8
  • OpenJDK 11
  • OpenJDK 17
  • OpenJDK 21

Oracle JDK 同样支持,覆盖相同的版本范围,依靠的是我们的调试符号重建技术。

同时,它也能运行在广泛的 Linux 发行版上,从最新内核到 RHEL/CentOS 7(Linux 3.10)等老系统皆可覆盖。

自动化采样和专家分析

OpenResty XRay 不仅提供了强大的分析功能,还具备自动化的采样和报告生成能力。为您的性能优化工作带来更多便利:

  1. 自动线上按需采样:XRay 能够根据预设条件自动触发采样,无需人工干预。这意味着您可以在特定负载或性能指标达到某个阈值时自动开始采集数据,确保捕捉到最关键的性能问题。

  2. 自动生成分析报告:基于采集到的数据,XRay 能够自动生成详细的分析报告。这些报告包含了性能热点、资源使用情况、潜在的优化建议等关键信息,让您能够快速了解应用的性能状况。

  3. 专家团队支持:除了自动化功能,我们的专家团队随时准备为您提供更深入的支持:

    • 根据您的具体需求,我们可以为您定制新的分析器,以满足特定的性能监控需求。
    • 我们的专家会协助您解读自动生成的报告,提供专业的见解和优化建议。
    • 如遇到复杂的性能问题,我们的团队可以提供更深入的分析和解决方案。

这是一份由 OpenResty XRay 生成的示例报告:

OpenResty XRay 生成的 Java 应用性能剖析报告——CPU、Off-CPU 与磁盘 I/O 总览

通过结合自动化工具和专家支持,OpenResty XRay 为您提供了一个全面的性能优化解决方案,帮助您的 Java 应用始终保持最佳性能状态。

性能影响和额外负担

OpenResty XRay 的设计理念是非侵入性和轻量级的。在采样时,添加到 Java 应用进程的额外负担通常非常小,可以忽略不计。而在不采样的时候,进程运行速度则完全不受任何影响。

这种低开销的特性使得 OpenResty XRay 成为理想的生产环境监控工具,让您可以随时随地进行性能分析,而不必担心对应用造成显著影响。

下一步的计划

我们并未止步于此。未来还有更多让 OpenResty XRay 对您来说更加强大和有用的计划。我们正在开发的一些功能包括:

  • 统计 Java 应用网络请求的延时情况,智能抓取问题请求的数据包。
  • 支持其他技术栈和开源软件。我们希望使 OpenResty XRay 成为一种通用工具,可以分析任何在线应用,无论底层技术是什么。我们考虑的一些目标包括 Nginx 模块,Envoy 扩展,PostgreSQL 扩展,Perl/Python/Ruby 模块和库,以及更多。

如果您有任何建议或对更多指标或功能的需求,请告诉我们。我们一直在倾听您的反馈,并持续改进我们的产品以满足您的需求。

常见问题

OpenResty XRay 需要 JVM agent 或 safepoint 吗?

不需要。OpenResty XRay 使用 eBPF+、Stap+ 等动态追踪运行时,而不是传统的 JVM agent,并且不依赖 JVM 的 safepoint 机制。因此,它生成的 CPU 火焰图不存在困扰传统 Java 采样分析器的 safepoint 偏差,也无需修改代码或添加特殊的 JVM 启动参数。

什么情况下需要为 Java 应用生成 Off-CPU 火焰图?

当 Java 应用的 CPU 使用率异常低时,原因通常是 I/O 阻塞、等待锁或其他资源竞争。OpenResty XRay 会为这类场景生成 Off-CPU 火焰图——例如,展示多个线程正在等待 BankSystem.java 第 76 行的 ReentrantLock:lock 调用。

支持哪些 OpenJDK 版本和 Linux 内核?

支持 OpenJDK 8、11、17 和 21,同样版本范围的 Oracle JDK 也支持,依靠的是我们的调试符号重建技术。在操作系统方面,OpenResty XRay 既能运行在现代 Linux 发行版上,也能运行在 RHEL/CentOS 7(3.10 内核)等较旧的系统栈上。

结论

在本文中,我们向您展示了如何使用 OpenResty XRay 来分析 Java 应用的 CPU 和硬盘 IO 使用情况。我们还向您展示了一些结果的示例,并解释了它们的含义。

通过使用 OpenResty XRay,您可以轻松找出那些消耗 CPU 和硬盘资源的代码路径,以及它们对整体性能有多大的影响。然后,您可以使用这些信息来优化您的 Java 应用,使其运行得更快更顺畅。

如果您想更多地了解 OpenResty XRay 产品以及它能够如何帮助您处理在线应用的其他方面的信息,请访问 我们的网站联系我们 以了解更多细节。

关于 OpenResty XRay

OpenResty XRay 是一个动态追踪产品,它可以自动分析运行中的应用,以解决性能问题、行为问题和安全漏洞,并提供可行的建议。在底层实现上,OpenResty XRay 由我们的 Y 语言驱动,可以在不同环境下支持多种不同的运行时,如 Stap+、eBPF+、GDB 和 ODB。

关于作者

章亦春是开源 OpenResty® 项目创始人兼 OpenResty Inc. 公司 CEO 和创始人。

章亦春(Github ID: agentzh),生于中国江苏,现定居美国湾区。他是中国早期开源技术和文化的倡导者和领军人物,曾供职于多家国际知名的高科技企业,如 Cloudflare、雅虎、阿里巴巴,是 “边缘计算 “、” 动态追踪 “和 “机器编程 “的先驱,拥有超过 22 年的编程及 16 年的开源经验。作为拥有超过 4000 万全球域名用户的开源项目的领导者。他基于其 OpenResty® 开源项目打造的高科技企业 OpenResty Inc. 位于美国硅谷中心。其主打的两个产品 OpenResty XRay(利用 动态追踪 技术的非侵入式的故障剖析和排除工具)和 OpenResty Edge(最适合微服务和分布式流量的全能型网关软件),广受全球众多上市及大型企业青睐。在 OpenResty 以外,章亦春为多个开源项目贡献了累计超过百万行代码,其中包括,Linux 内核、Nginx、LuaJITGDBSystemTapLLVM、Perl 等,并编写过 60 多个开源软件库。

关注我们

如果您喜欢本文,欢迎关注我们 OpenResty Inc. 公司的 博客网站 。也欢迎扫码关注我们的微信公众号:

我们的微信公众号

翻译

我们提供了 英文版 原文和中译版(本文)。我们也欢迎读者提供其他语言的翻译版本,只要是全文翻译不带省略,我们都将会考虑采用,非常感谢!