使用 Arthas 排查高 CPU 使用率问题
Arthas (阿尔萨斯) 是一个非常强大的 Java 在线诊断工具,特别适合在生产环境中排查问题。 它可以让你在不重启应用的情况下,动态地观察和修改 Java 应用程序的行为。 以下是如何使用 Arthas 来排查高 CPU 使用率问题的步骤,并说明各种命令的用途:
1. 安装和启动 Arthas:
- 下载 Arthas:
wget https://arthas.aliyun.com/arthas-boot.jar - 启动 Arthas:
java -jar arthas-boot.jar - 选择要诊断的 Java 进程。 Arthas 会列出当前正在运行的 Java 进程,选择目标进程的编号。
2. 使用 dashboard 命令查看系统信息和线程状态:
-
输入
dashboard命令,Arthas 会显示一个实时更新的仪表盘,包含:- 系统信息 (CPU, Memory, Load Average)
- JVM 信息 (GC, Thread)
- 线程信息 (ID, Name, State, CPU%, TIME)
-
观察线程信息,找到 CPU 使用率最高的线程 ID (NID)。
dashboard命令会动态更新,方便你快速找到占用 CPU 最高的线程。
3. 使用 thread 命令查看线程堆栈信息:
-
输入
thread <NID>命令,其中<NID>是你在dashboard中找到的 CPU 使用率最高的线程的 Native ID。 例如:thread 21这会打印出该线程的堆栈信息。 堆栈信息显示了线程当前正在执行的代码路径。
-
分析堆栈信息,找出导致高 CPU 使用率的代码。 常见的嫌疑对象包括:
- 无限循环: 检查是否有任何循环没有正确的退出条件。
- 正则表达式: 复杂的正则表达式可能会导致 CPU 使用率飙升。
- I/O 操作: 频繁的磁盘或网络 I/O 操作也可能导致问题。
- 计算密集型操作: 复杂的算法或计算可能会占用大量 CPU 资源。
4. 使用 trace 命令追踪方法执行耗时:
-
trace命令可以追踪指定方法的执行耗时,帮助你找到性能瓶颈。 -
语法:
trace <class name> <method name> -
例如,假设你在线程堆栈中发现
com.example.MyClass.processData()方法可能存在问题,可以使用以下命令追踪该方法的执行耗时:trace com.example.MyClass processData -
Arthas 会打印出每次调用
processData()方法的耗时。 如果发现某个方法的耗时特别长,则很可能是性能瓶颈所在。
5. 使用 watch 命令观察方法参数和返回值:
-
watch命令可以观察指定方法的参数和返回值,帮助你理解方法的行为。 -
语法:
watch <class name> <method name> "{params,returnObj}" -
例如,继续使用上面的例子,可以使用以下命令观察
processData()方法的参数和返回值:watch com.example.MyClass processData "{params,returnObj}" -
Arthas 会打印出每次调用
processData()方法的参数和返回值。 这可以帮助你了解方法的输入和输出,从而更好地理解方法的行为。
6. 使用 profiler 命令进行 CPU 火焰图分析:
-
profiler命令可以生成 CPU 火焰图,帮助你更直观地了解 CPU 的使用情况。 -
启动 profiler:
profiler start -
运行一段时间后,停止 profiler:
profiler stop -
Arthas 会生成一个 HTML 文件,其中包含 CPU 火焰图。 在浏览器中打开该 HTML 文件,就可以看到 CPU 的使用情况。
-
火焰图的每一层代表一个函数调用,火焰越宽表示该函数占用的 CPU 时间越多。 通过火焰图,可以快速找到占用 CPU 最多的函数。
7. 使用 tt 命令记录和回放方法调用:
-
tt命令 (Time Tunnel) 可以记录指定方法的调用,并在之后回放这些调用。 这可以帮助你重现问题,并进行更深入的分析。 -
语法:
tt -t <class name> <method name> -
例如:
tt -t com.example.MyClass processData -
这会记录
processData()方法的所有调用。 记录完成后,可以使用tt -l命令列出所有记录的调用,并使用tt -i <index>命令回放指定的调用。
排查示例:
- 使用
dashboard找到 CPU 使用率最高的线程 (例如,NID 为 21)。 - 使用
thread 21查看该线程的堆栈信息。 发现线程正在执行com.example.MyClass.processData()方法。 - 使用
trace com.example.MyClass processData追踪processData()方法的执行耗时。 发现该方法的执行耗时非常长。 - 使用
watch com.example.MyClass processData "{params,returnObj}"观察processData()方法的参数和返回值。 发现该方法接收的参数数据量非常大,导致执行缓慢。 - 使用
profiler start和profiler stop命令生成 CPU 火焰图,并在浏览器中打开火焰图。 火焰图显示processData()方法及其调用的子方法占用了大量的 CPU 时间。
根据以上信息,可以判断 processData() 方法是性能瓶颈所在。 接下来,可以优化该方法的代码,例如减少数据量、使用更高效的算法等。
总结:
Arthas 提供了丰富的命令,可以帮助你从多个角度分析 Java 应用程序的性能问题。 熟练掌握这些命令,可以让你在生产环境中快速定位和解决问题。 记住,Arthas 是一个强大的工具,但也要谨慎使用,避免对生产环境造成不必要的影响。 在进行任何操作之前,请务必了解该操作的含义和潜在风险。 推荐优先在测试环境中进行验证。

浙公网安备 33010602011771号