本文概览:描述了load飙高的概念、触发load飙高因素以及load飙高之后该如何做。
1 load介绍
1.1 什么是load
load的在一段时间内CPU正在处理以及等待CPU处理的进程数之和的统计信息,也就是CPU使用队列的长度的统计信息,举例如下:
假设一个CPU每分钟处理100个线程。假设此时一分钟内处理了20个线程时,此时load值为0.2。如果load值为1.5,说明cpu正在同时处理100个线程之外,在阻塞队列中海油50个线程等待。
1.2 load的合理值
1、load的含义
1 |
load飙高就是CPU使用率高了;如果是内存飙高,就会出现swap报警。 |
2、查看
(1)通过uptime系统load的值。
可以uptime命令可以显示的信息显示依次为:现在时间、系统已经运行了多长时间、目前有多少登陆用户、系统在过去的1分钟、5分钟和15分钟内的平均负载。
1 2 |
$ uptime 11:10:00 up 758 days, 13:51, 3 users, load average: 0.07, 0.08, 0.12 |
(2)通过top也可以查看
1 2 3 4 5 6 7 |
$top top - 14:06:13 up 676 days, 20:05, 4 users, load average: 0.45, 0.46, 0.44 Tasks: 393 total, 2 running, 387 sleeping, 0 stopped, 4 zombie Cpu(s): 2.8%us, 1.9%sy, 0.9%ni, 94.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 49421880k total, 44470668k used, 4951212k free, 521472k buffers Swap: 0k total, 0k used, 0k free, 33807500k cached |
3、load值合理值是多少呢?
参考如下:http://www.ruanyifeng.com/blog/2011/07/linux_load_average_explained.html
当这个值达到0.7,就应当引起注意了。经验法则是这样的
(1)当系统负荷持续大于0.7,你必须开始调查了,问题出在哪里,防止情况恶化
(2)当系统负荷持续大于1.0,你必须动手寻找解决办法,把这个值降下来。
(3)当系统负荷达到5.0,就表明你的系统有很严重的问题,长时间没有响应,或者接近死机了。你不应该让系统达到这个值。
2 load问题分析
1、第一步 找到CPU最高进程
在实际的分析问题中,通过“ps -ef| grep 应用名称“或者jps来选择我们的应用ID。因为一个服务器上可以部署多个应用,查找自己要排查问题的那个应用的进程ID,并jstack出这个应用的信息。
2、第二步 jstack 导出进程堆栈信息
命令
1 |
jstack -l 进程ID > 输出文件 |
如果没有打印出信息可以使用-F,如下
1 |
jstack -F 进程ID > 输出文件 |
3 .第三步 查看指定进程的占CPU较高的线程,查找这个线程是为了在分析jstack出来的信息时使用。
(1)命令
1 |
top -H -p 应用的进程ID |
其中:
- -H 表示线程
- -p 指定进程ID
在输出结果中可以 TIME列就是各个Java线程耗费的CPU时间,CPU时间最长。可以通过 按 T 来刷新top结果。切换排序的参数如下:
- T,表示按执行时间排序。一般使用功能这个参数来表示CPU使用率。
- M,表示按内存排序
- P,表示按CPU排序(建议使用T)
(2) 将线程id转换为16进制,使用shell命令为
1 |
printf %x 28034 |
4. 第四步 分析jstack新
在jstack导出信息中根据上述的线程id的十六进制通过grep来定位到出问题线程的信息(即,出现问题的代码)
3 线程哪些问题会引起load偏高
3.1 阻塞
1. 查看执行时间最长的723e,如下。发现了“wait on condition”
搜索wait on condition:
从时上图中可以找到
1 2 |
at javalearn.jvm.Action.run(Action.java:14) at javalearn.jvm.TestLoad$OneTask.run(TestLoad.java:18) |
3.2 死循环
通过查看执行时间最长的那个线程ox6f21,定位如下
由上可以获取如下信息:
- 发现此时线程状态为Runalbe
- 还可以定位到代码: Action.java 16
3.3 GC飙高时
Gc飙高导致cpu飙高
附
关于top命令,如果直接使用H、M、P无法进行排序时,可以通过如下方法:
在运行top时,通过输入?来查看参数
(1)在运行top时,输入 o,此时会出现如下行。
(2)输入time,如下,此时就会按照时间进行排序
(全文完)