性能分析小案例系列,可以通过下面链接查看哦
https://www.cnblogs.com/poloyy/category/1814570.html
ps:这些分析小案例不能保证完全准确哦,是博主学习过程中的总结,仅做参考
前提
本机有一个很占用 CPU 的项目,放在了 Tomcat 下启动着
如何定位
Jmeter 聚合报告
- 可以看到平均响应时间不断的上升,但是吞吐量(TPS)很低
- 平均响应时间一般超过 1s,就要排除网络有没有瓶颈
排查网络是否有瓶颈
在 cmd ping 自己的服务器 ip 地址,看是否有很大的延时或丢包
可以看到,没有丢包,而且延时也很低,证明网络没有问题
在服务器中,通过 top 查看是否有进程的用户态(us)过高
top
- 可以看到是 Java 进程导致 CPU 使用率贼高,已经占满了四个 CPU
- 记住该进程 PID
通过 ps 命令确认具体是哪个进程
ps -aux | grep 2838
很明显,就是我们 Java 程序所在的 Tomcat 进程啦
通过 top 查看 Java 进程的线程执行情况
2838 是进程 id 哦(pid)
top -Hp 2838
- 上面的 PID 就是线程的 PID
- 按照线程的 CPU 使用率从高到低排序
将排在前面的线程 PID 转换成十六进制
printf "%x\n" 4808
打印 Java 线程栈的信息
jstack 2838 | grep 12c8 -A30
- 2838:java 进程
- 12c8:线程十六进制
- -A30:打印 30 行
- 包含:包名、类名、代码行信息,可以快速定位到某行代码导致该线程 CPU 使用率过高
- jstack:JDK 自带命令
分析思路过程
- 使用 Jmeter 进行压测,通过观察聚合报告,发现 TPS 很低只有2.几,但是响应时间很高
- 响应时间很高首先要排查是否是网路原因,通过 ping 服务器的 IP 发现延时很低,不存在网络问题
- 通过 top 查看服务端的系统资源情况,发现用户态 CPU 使用率比较高,即存在占用 CPU 高的进程,查看进程列表,发现一个 Java 进程的 CPU 占用率特别高
- 通过 ps 命令确认该进程的详细信息
- 通过 top -Hp 查看该进程的所有线程信息
- 将排在前面的 Java 线程号打印成 16 进制字符串
- 通过 jstack 打印 Java 线程栈的信息,可以发现是某一行代码的问题