一、指标
通常应用服务性能关注以下两方面的指标:
下面将主要是基于CPU指标进行实验模拟分析,下面是一些命令下,cpu指标:
1、top 命令下个字段含义,参考:https://www.jianshu.com/p/078ed7895b0f
2、vmstat 命令:
us:用户占用CPU的百分比
sy:系统(内核和中断)占用CPU的百分比
id:CPU空闲的百分比
二、实验
1、环境:Linux 2.6.32-696.18.7.el6.x86_64
2、流程:通过Jmeter 对服务接口进行压测,模拟高并发访问,从而使CPU负载飙升。
3、接口代码:
public PlainResult<String> test() throws InterruptedException{
Integer n =0;
synchronized(locka){
try{
for(;;){
if(n < Integer.MAX_VALUE){
continue;
}
n++;
}
}catch (Exception e){
log.info("报错啦");
}
}
return ResultUtils.createSuccessResult("true");
}
4、JEMET 测试:线程数=100 ,循环调用:
三、分析
此时,用户已经感知服务非常的慢,作为开发人员需要定位问题出在哪,以下是基本步骤。
1、首先,我们不知道是哪方面出现了性能问题,因此可以先整体看下服务的性能,通过vmstat 可以获取:
从上图可以看出,内存、io等无性能瓶颈,但是CPU指标us(用户占用CPU的百分比)非常高,几乎接近100,id(CPU空闲的百分比)-->0,但是sy不高,另外in(系统中断)和cs(上下文切换)的数值非常高,这里可以猜测是用户应用中有大量的线程切换。
2、jps -l 查看有哪些Java进程:
可以看到,服务器上只有一个应用服务,其进程pid=24244
3、此时可用top命令可以查看具体信息:
从上图中可以看到,进程pid=24244一直cpu占用很高,基本可以定位到是该应用出现了性能瓶颈问题。
4、jstack -l 24244 > /data/logs/retail-scrm/test/24244.log dump出该进程下所有线程的堆栈信息.
5、使用 top -H -p 24244 进一步找出高占用CPU的线程:
从图中可以看出线程为30654 的一直占用着资源。
6、printf "%x" 30654 输出对应16进制的线程号:77be:
7、进入24244.log 找到对应线程的堆栈信息:
可以看到在该方法中,获取了一个Object对象锁(private static Object locka = new Object();),而大量的其他线程则被阻塞等待锁的释放。
在找到应用中对应的代码,分析其合理性即可。
以上是简单的模拟线上可能出现的性能问题:主要是通过常用命令查看服务器相关指标,并通过dump进程相关堆栈信息来定位应用中可能出现性能问题的节点。文章有不对之处,诚邀斧正,你的批评是我前进的最大动力!