1、现象
(1)服务器的CPU使用率比较高(>80%)
(2)TPS波动非常大
(3)狂打超时日志,偶尔有500错误
2、思路
(1)接口的性能非常好,比如响应时间<10ms,TPS很高,此时CPU使用率高是正常的,不需要优化
(2)接口性能不好,比如响应时间>200ms,TPS很低,此时需要考虑优化
3、案例
(1)测试人员监控到CPU占用较高,top命令显示CPU和负载如下
(2)开发用jconsole监控内存,发现内存使用不正常,内存回收非常频繁,差不多5分钟进行一次,而且内存回收不彻底,回收的量很少,每次回收后使用量依然在1G左右徘徊。
(3)开发继续使用ps -ef|grep java|grep -v grep获得Java进程ID是8071。使用jstat -gcutil 8071 3000看了下gc的情况,fgc很频繁
到这里我们已经可以定位是内存问题,FGC频繁导致了CPU占用较高,超时严重所以我们看到TPS波动大。
那么是谁吃了我的内存?
(4)开发继续用JvisualVM工具分析,发现内存中有大量回收不掉的对象,分析dump文件,点击class,根据size排序,找到比较大且比较熟悉的实例,终于知道这些回收不掉的内存是哪里来的了。
(5)问题根因:
这些回收不掉的对象都是用例做接口参数校验的,于是开发分析了测试发送的接口请求,发现测试人员发送的消息中没有填写接口参数的原因,让测试人员按照接口文档要求构造请求消息后重新压测,就没有再出现频繁内存回收的情况。