场景

测试环境,内部帐户登录之后,测试机负载非常高  

image
究竟问题是什么呢?

工具

  • 【jps】:jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简单察看当前java进程的一些简单情况。

  • 【pidstat】: pidstat主要用于监控全部或指定进程占用系统资源的情况,如CPU,内存、设备IO、任务切换、线程等。pidstat首次运行时显示自系统启动开始的各项统计信息,之后运行pidstat将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。

  • 【jstack】:jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式。

排查步骤

1、登录服务器,使用jps查看结果如下:  
web@/home/www$ jps    
11493 Bootstrap    
13022 Jps

2、使用pidstat查看查看结果如下:  
web@/home/www$ pidstat -p 11493 -u 1 3 -t    
Linux 2.6.32-5-amd64 (debian-mongodb-test01) 2014年04月03日 x86_64 (2 CPU)

13时09分09秒 TGID TID %usr %system %guest %CPU CPU Command  
13时09分10秒 11493 - 194.39 2.80 0.00 197.20 1 java    
13时09分10秒 - 11493 0.00 0.00 0.00 0.00 1 |__java    
13时09分10秒 - 11494 0.00 0.00 0.00 0.00 1 |__java    
13时09分10秒 - 11495 7.48 1.87 0.00 9.35 1 |__java    
13时09分10秒 - 11496 9.35 0.00 0.00 9.35 0 |__java    
13时09分10秒 - 11497 0.00 0.00 0.00 0.00 0 |__java    
...中间忽略    
平均时间: - 11669 78.66 0.33 0.00 28.99 - |__java    
平均时间: - 11670 88.66 0.33 0.00 28.99 - |__java

问题锁定:TID=11669|11670的java

3、导出Java应用程序所有线程  
jstack -l 11493 > /home/www/tmp.txt    
TID=11670的java,11670转换为16进制是0x2d96    
在tmp.txt中查找nid=0x2d96

如图  

image

锁定了:

BusinessSubscriptionService.getBusinessSusbscriptions(BusinessSubscriptionService.java:65)

BusinessSubscriptionService.getBusinessSusbscriptionsOfLoginUser(BusinessSubscriptionService.java:175)


询问开发检查问题所在。

结果开发反馈:

重构有风险,测试需谨慎。 这个错误的重构会导致进入带宽查询加载业务订阅时,错误的查询了当前内部帐号绑定的所有账户(多达4000多个)的业务订阅,因此导致CPU负载高,tcp连接数高,页面一直在等待响应。