几种常见的定位排查手段

公众号:yunops

一、场景描述

在实际应用场景中,JAVA 进程导致宿主机 CPU 使用率高的情况很常见,可能导致的原因很多:主机配置过低、代码质量低等;通常处于 bug 修复或者性能优化的需求,需要定位耗费大量 CPU 时间的罪魁祸首,这里提供几种常见的定位排查手段。

二、可选排查方式

【方式一】命令行 + jstack

jstack 是 Java 进程内的线程堆栈信息的常用工具,具体使用如下:

  1. 定位消耗 CPU 的进程 pid(按 P 排序):top -c
  2. 可以将进程堆栈导出:jstack -l <pid> > jstack.txt,然后加载到本地客户端工具或者网页工具(如:heapdump)中进行分析
  3. 也可以完全使用命令行分析,定位消耗 CPU 的具体线程及其堆栈:top -Hp <pid>;输入 P 按 CPU 使用率排序,记住线程 pid 并转化为 16 进制:printf '%x\n' <nid>,得到 16 进制的 nid-16;接着在 jstack 中找到对应堆栈信息:jstack -l <pid> | grep <nid-16> -C5 -color 或者 jstack -l <pid> | grep <nid-16>
  4. 检查 JAVA 进程是否存在死锁:jstack -l -F <pid>
【方式二】Arthas

Arthas 是 Alibaba 开源的一个 Java 诊断工具,方便进行问题的定位和诊断,可以在线排查问题,无需重启;动态跟踪 Java 代码;实时监控 JVM 状态。

  1. 下载 jar 包:curl -O https://alibaba.github.io/arthas/arthas-boot.jar
  2. 使用和业务应用相同的用户运行调试命令(会进入专用控制台并自动识别 java 进程并提供序号列表供选择):java -jar arthas-boot.jar
  3. 使用说明:
    • 输入help命令查看支持的选项,dashboard命令用于整体展示进程所有线程、内存、GC 等情况,通过thread-n 5选项找出最忙的前 5 个线程、-b 选项找出阻塞其他线程的线程,再输入thread <nid>查看详情,使用trace或者tt命令进行跟踪分析,输入stop退出。
    • profiler命令支持生成应用热点的火焰图,默认生成的是 cpu 的火焰图(即 event 为 cpu,可以用 –event 参数来指定,支持的 event 可以使用profiler list命令获取), 常规命令:
      1. 启动采样:profiler start
      2. 查看已获取的样本数:profiler getSamples
      3. 查看采样状态:profiler status
      4. 停止采样:profiler stop(支持通过--file指定保存的文件名、--format html指定输出为 html 格式,默认为 svg)
【方式三】show-busy-java-threads 脚本
  1. 下载安装包:wget --no-check-certificate https://github.com/oldratlee/useful-scripts/archive/release.zip
  2. 解压:unzip release.zip && cd useful-scripts-release
  3. 使用(找出指定 java 进程中最消耗 CPU 的线程(缺省 5 个),打印出其线程栈):./show-busy-java-threads -p <pid>