jvm 调优-排查线上 cpu 使用率高的问题

·  阅读 2876
jvm 调优-排查线上 cpu 使用率高的问题

「这是我参与 2022 首次更文挑战的第 7 天,活动详情查看:2022 首次更文挑战

仁者见之谓之仁,智者见之谓之智。

在工作是和面试中,都会被问到一些调优的内容,比如 mysql jvm tomcat 之类的,因为这个问题比较大,今天就只说一点,也是面试会遇到的问题,线上排除 cpu 长时间超过 100%的问题。这里需要强调的是,top 命令展示的 cpu 使用率是总体的,单个 cpu 的使用率要除以 cpu 的核数才能得到结果。

通常的排查步骤如下:

  • 1 通过 top 命令找到消耗 cpu 高的进程 id 号 pid
  • 2 根据 pid 找到消耗 cpu 资源比较高的线程 id
  • 3 对当前的线程做 stack,输出前进程的所有堆栈信息
  • 4 将第 2 步中得到的线程 id 转换成 16 进制进得到结果
  • 5 根据相应的线程 id 在堆栈信息中找到相关的内容
  • 6 解读对应的堆栈信息,定位代码位置并排查问题原因

1 定位进程

在 linux 系统中,一般使用 top 或者 ps 命令来定位查找进程信息。假设我们找出来了一个进程号为 19505 的应用。

# 查看 top 命令 按 x 按 cpu 进行排序
top -d 2
# 如果确定是 java 进程,可以使用ps 命令来查号进程
ps -aux | grep java
# 如果觉得top 命令显示的数据太多,可以使用以下命令,只展示前几行
top | grep "top - " -A 8
复制代码

2 查找线程信息

查找进程内的线程情况,可以使用 ps 或者 top 命令来查看,查看进程 19505 内的线程信息。

# ps 查看进程的 pid 线程情况 -o 后面是打印输出列
ps -mp 19505 -o THREAD,tid,time
# 使用 top 命令查看当前进程内的线程情况
top -Hp 19505 -d 1 -n 1
# 使用 shell 的打印命令将线程高的线程 id 转换成 16进制,假设我们找到了一个线程ID 为 89043 ,那么转换成 16 进制就为 15bd3。
printf "%x\n" tid
复制代码

3 查找线程堆栈情况

打印线程堆栈信息,需要使用 jvm 自带的命令 jstack , 当因当前进程的信息,然后使用 grep 命令直接匹配搜索线程相关情况。或者将线程堆栈信息存储为文本,然后再进行搜索查找。使用 jstack 命令查询堆栈信息

#  查看 19505 进程的 tid=15bd3 线程的堆栈情况
jstack 19505 |grep tid -A 30
# 使用 jstat 查看 gc 信息和内存使用情况
jstat -gc 或者 jstat -gcutil
复制代码

总结

一般情况下,排查线上 cpu 飙高的步骤已经说明,但是基本没有哪家公司允许线上排除问题的,从线上摘掉有问题的服务进行操作观察处理。在实际工作中,这种操作一般不常见,99%的问题可以通过日志就能定位问题,复杂的系统也有相应的链路追踪系统,用到这种操作的基本不多,只是在面试的时候会用到,考察的点也是对 jvm 和 linux 操作系统的熟练程度。

分类:
后端
标签:
分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改