性能优化-快速定位性能问题(postman+top+jstack+jstat+free+本机热部署调试)
背景
功能问题容易定位,性能问题则需要立体化的分析才可以找到具体原因。本博客将阐释一次项目过程中的实战。
注:由于本博客在起草时,问题已经解决,所以命令的执行截图仅供参考。
问题现象
某接口进行压测过程中出现诡异现象:
- 偶尔会出现秒级的返回,甚至是超时
- 单数据多用户压测不存在问题,参数化数据后多用户压测存在问题,有极长请求(3s以上的超时)
定位过程
使用脚本查看busy线程
推荐脚本:https://github.com/oldratlee/useful-scripts.git
下载后,直接使用./show-busy-java-threads -p pid
命令运行效果如下:
注意:由于本次运行时已经解决问题,所以上图仅供参考而已
可以看到,排名靠前的线程是什么类型的。我在分析问题的时候,明显看到是gc线程。
那么说明gc可能存在问题。
特别说明:
脚本本身是使用top和jstack命令的结合,从而打印出了jstack的快照信息。
使用jstat查看gc情况
jstat -gc -t -h3 32596 1000
查看gc情况。jstat的命令使用参考博客java-jdk自带监测工具(jstat)
重点看“full gc的数量”和“full gc的时间”。
从当时的数据来看,full gc数量已经超过了1000次,耗时是100s+,说明在频繁的进行fgc,而且在这100s内,服务只能进行stop the world。
free查看内存
free -m
查看测试环境机器的内存情况
free表示空闲内存,当时的空闲内存只有200mb左右
available表示可用内存,当时应该是在1个多g左右。
fgc频繁的原因之一可能就是:测试环境 在压测时内存吃紧了。
在个人pc运行
在个人pc运行,并且压测,可以排除机器内存不足的问题。
- 重新进行本机pc压测(数据没有进行参数化)。压测结果表现正常,有进展。。。
- 进行本机pc压测(数据参数化),又出现了新的问题,
请求超时
。
逐个排查参数,最后发现,使用一个childId去请求,会出现超时问题。
剩下的就好说了,既然超时是必现的,那么直接进行代码调试吧。
热部署代码调试
最快的调试思路是:
- debug启动服务
- 在怀疑的地方添加打印(利用save action的热部署机制,很快的进行编译)
- 一直找到卡住的位置
idea的save action插件使用参考博客效率提升-idea插件(save action)
中间过程截图如下:
最终找到了性能问题的位置。从数据库中读取的数据量太大,在循环处理过程中出现了耗时现象。
评价
服务性能问题定位需要使用不同的检测工具
- jvm监测工具
- linux监测工具
- 甚至可以使用链路调用监测工具
这里非常考验平常的积累。