- 系统瓶颈的定位
本文由于涉及内容比较多,可能会不定期更新修改内容,敬请留意
- 目的:
- 场景:
小维:过来看看,你的程序跑满CPU了,现在系统load average很高呢!
小程:嗯,是喔。是不是JVM配的太小啦,加大点啊,难道这台机器要加内存呢?
- 分析:
真的能解决吗,我们看看下面正确的分析方法。
top - 16:44:01 up 1277 days, 20:51, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 214 total, 1 running, 213 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.1%us, 0.1%sy, 0.0%ni, 99.6%id, 0.2%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1035136k total, 1016708k used, 18428k free, 73884k buffersSwap: 2076208k total, 1038104k used, 1038104k free, 112100k cached
上面是top命令出来结果,里面有个很重要的指标是load average,它的含义是系统中处于运行状态的进程的队列长度。
它一定程度反映了系统忙的程度,数值越大,表示系统越忙,用逗号分开的三个数值表示是最近1分钟,5分钟,15分钟的平均数。
系统变忙,绝大多数load average都是变高的,但是这个变高只是表示排队等待CPU处理的进程队列变长,但是为什么会变长?
这就要看其他系统参数来确定。
我简单把系统资源粗略的分成3大类:CPU,内存,IO。
还是通过上面的top命令结果,我们注意以下这句
Cpu(s): 0.1%us, 0.1%sy, 0.0%ni, 99.6%id, 0.2%wa, 0.0%hi, 0.0%si, 0.0%st
具体每一个数值的含义我就不一一列出来,因为就算把那么多的含义列出来,读者真正记得的也只是自己想知道的那几个,所以我这里就只说需要知道的那个。
我们判断IO是否有瓶颈一般看wa就可以了,如果这个数字长期达到50+的话,那么证明系统的IO已经负荷过大,
因为上面列举的资源3大类来说,IO是最容易瓶颈的,所以有经验的运维人员一般是排查IO是否有问题。
假如这一步就确定是IO问题了,下面怎么继续呢?
IO包括两方面:磁盘和网络两大块,磁盘可以用iostat这个工具来判断,网络可以用ifconfig和netstat来判断,具体这里就不展开了。
接上面,假如IO没问题,那就先回归调查内存。
- 定位系统瓶颈有很多工具,具体请看:
然而我们的场景是java程序,java程序一个很重要的概念是JVM。
- jvm的知识看我另一篇文章:
了解完jvm基础知识后,可以使用jdk的性能监控工具:jps、jinfo、jstat、jmap、jstack等获取jvm的性能状态或者堆栈信息
获取jvm信息的步骤为
jps | 获取java进程pid |
jinfo | jvm运行参数信息 |
jmap | 获取堆内存使用情况 |
jstat | 获取gc次数和耗时 |
jvm一般常见的异常情况有:
fgc过多,需要调整新生代和老生代的内存比例;
jstack出来的堆栈信息有死锁,一般是代码问题,需要开发debug;
堆内存不够使,这个只好把jvm的内存参数酌情增大,再运行试试;
某种类的对象过多,最好通过jprofile观察,是否死循环不断生成对象或者是对象回收过程有问题;