一、top命令查看系统cpu使用率与负载
1.1 cpu使用率与负载之间的关系
cpu使用率代表cpu被利用的时间占比,如果一个进程占用cpu但是不使用,使用率是可能会为0的。而load则是排队使用cpu的人同时有多少。如果一个cpu同时有5个进程要使用,那么load就是5。
1.2 top命令使用
css
top 查看系统cpu的使用状态
css
top 之后按1 可以查看每个cpu的使用状态
css
查看每个进程里面每个线程占用cpu的状态
top -H -p pid
cpu进程相关:
属性 | 含义 |
---|---|
load average | 系统负载,即任务队列的平均长度。三个数值分别为 1分钟、5分钟、15分钟前到现在的平均值。 |
total | 进程总数 |
running | 正在运行的进程数 |
sleeping | 睡眠的进程数 |
stopped | 停止的进程数 |
zombie | 僵尸进程数 |
Cpu(s):us | 用户空间占用CPU百分比 |
Cpu(s):sy | 内核空间占用CPU百分比 |
Cpu(s):ni | 用户进程空间内改变过优先级的进程占用CPU百分比 |
Cpu(s):id | 空闲CPU百分比 |
Cpu(s):wa | 等待输入输出的CPU时间百分比 |
Cpu(s):hi | 硬件CPU中断占用百分比 |
Cpu(s):si | 软中断占用百分比 |
Cpu(s):st | 虚拟机占用百分比 |
内存相关:
属性 | 含义 |
---|---|
Mem:total | 物理内存总量 |
Mem:used | 使用的物理内存总量 |
Mem:free | 空闲内存总量 |
Mem:buffers | 用作内核缓存的内存量 |
交换区相关:
属性 | 含义 |
---|---|
Swap:total | 交换区总量 |
Swap:used | 使用的交换区总量 |
Swap:free | 空闲交换区总量 |
Swap:cached | 缓冲的交换区总量,内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖,该数值即为这些内容已存在于内存中的交换区的大小,相应的内存再次被换出时可不必再对交换区写入。 |
进程信息区统计信息区域的下方显示了各个进程的详细信息:
序号 | 列名 | 含义 |
---|---|---|
a | PID | 进程id |
b | PPID | 父进程id |
c | RUSER | Real user name |
d | UID | 进程所有者的用户id |
e | USER | 进程所有者的用户名 |
f | GROUP | 进程所有者的组名 |
g | TTY | 启动进程的终端名。不是从终端启动的进程则显示为 ? |
h | PR | 优先级 |
i | NI | nice值。负值表示高优先级,正值表示低优先级 |
j | P | 最后使用的CPU,仅在多CPU环境下有意义 |
k | %CPU | 上次更新到现在的CPU时间占用百分比 |
l | TIME | 进程使用的CPU时间总计,单位秒 |
m | TIME+ | 进程使用的CPU时间总计,单位1/100秒 |
n | %MEM | 进程使用的物理内存百分比 |
o | VIRT | 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES |
p | SWAP | 进程使用的虚拟内存中,被换出的大小,单位kb。 |
q | RES | 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA |
r | CODE | 可执行代码占用的物理内存大小,单位kb |
s | DATA | 可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb |
t | SHR | 共享内存大小,单位kb |
u | nFLT | 页面错误次数 |
v | nDRT | 最后一次写入到现在,被修改过的页面数。 |
w | S | 进程状态(D=不可中断的睡眠状态,R=运行,S=睡眠,T=跟踪/停止,Z=僵尸进程) |
x | COMMAND | 命令名/命令行 |
y | WCHAN | 若该进程在睡眠,则显示睡眠中的系统函数名 |
z | Flags | 任务标志,参考 sched.h |
更改显示内容通过 f 键可以选择显示的内容。
常用top命令操作
scss
top //每隔5秒显式所有进程的资源占用情况
top -d 2 //每隔2秒显式所有进程的资源占用情况
top -c //每隔5秒显式进程的资源占用情况,并显示进程的命令行参数(默认只有进程名)
top -p 12345 -p 6789//每隔5秒显示pid是12345和pid是6789的两个进程的资源占用情况
top -d 2 -c -p 123456 //每隔2秒显示pid是12345的进程的资源使用情况,并显式该进程启动的命令行参数
查看系统cpu核数量的命令
CPU核心通常指的就是CPU Core,意思是部分CPU处理单元。简单来说,一个CPU(中央处理单元)可能有一个或多个核心,这些核心可以同时处理不同的任务,从而提高计算机的性能和多任务处理能力。
在多核心CPU系统中,操作系统将可以同时执行更多的线程或进程,这样可以更有效地处理多任务负载。这就是为什么在解释load average时需要考虑CPU核心数量的原因。每个核心基本上可以视作一个可以独立处理任务的单元。因此,当你在评估系统负载时,一个核心的设计允许一定程度的并行处理能力。
bash
# 总核数 = 物理CPU个数 X 每颗物理CPU的核数
# 总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数
# 查看物理CPU个数
cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo| grep "cpu cores"| uniq
# 查看逻辑CPU的个数
cat /proc/cpuinfo| grep "processor"| wc -l
二、如何通过top命令给出的信息来判断程序是否健康
2.1 load与cpu使用率之间的关系
cpu反应的是采样时间内cpu的使用情况,如果cpu高说明当前cpu处于忙碌状态
load表示当前系统正在使用cpu、等待使用cpu、等待io的进程数量,top中3个时间表示1分钟、5分钟、15分钟的平均值
他们的关系是如果cpu较高但是load不高,小于核数量,说明系统处于忙碌状态但是在承受范围内,并没有超过负荷
。如果load大于核数量说明有进程在等待使用cpu,系统处于超过负荷状态,需要排查问题,不然可能不久就会崩溃
load average的值是代表系统在最后1分钟、5分钟和15分钟内的平均进程数量,既然处于可运行状态(正在运行或者等待运行)的进程。这个数值并不直接分开每个CPU的负载,而是整个系统的负载。
在多核(CPU)系统中,load average的值可以这样解读:
- 如果load average小于或接近CPU的核心数量,那么系统负载是在合理范围内的。
- 如果load average等于CPU的核心数量,那么系统正好饱和,每个CPU核心都在忙碌中,没有空闲。
- 如果load average大于CPU的核心数量,那么意味着存在过载情况,有进程需要等待CPU资源。
例如,假设一个系统有4个CPU核心,如果此时load average输出是 1.00, 2.00, 3.00,这意味着在过去的1分钟内平均有1个进程在等待或使用CPU,过去5分钟平均是2个,过去15分钟平均是3个。因为这些数值都小于4(CPU核心数),说明系统并没有过载。
这些值若是 4.00, 8.00, 12.00,那么在过去的1分钟内平均有4个进程同时运行,系统正好满载,而在过去5分钟和15分钟内,系统有明显的过载。
总之,load average提供了一个系统平均负载水平的快照,但是解释它的值时,需要考虑到CPU核心的数量。在多核心环境中,load average的数值实际上可以超过1而不一定表示系统过载,关键要看这个数值与CPU核数的关系。
2.1 load的监控标准
- 0.7/每核:需要注意并排查原因 。 如果平均负载保持在> 0.70以上,那么应该在情况变得更糟之前进行调查。
- 1.0/每核:不紧急,需要处理。如果平均负载保持在1.00以上,需要查找问题原因并立即解决。否则,你的服务器可能在任何时候出现性能问题。
- 5.0/每核:紧急状态,立即处理。如果平均负载高于5.00,那么你的系统马上就要崩溃了,很有可能系统挂机或者hang死。因此需要立即处理这种情况,千万不要让你的系统负载达到5!
2.2 高load的5种可能
- 死循环或者不合理的大量循环操作,如果不是循环操作
- 也可能有大量的序列化反序列化操作,除此之外按照现代cpu的处理速度来说处理一大段代码也就一会会儿的事,基本对能力无消耗
- 频繁gc,比如YoungGC、FullGC、MetaspaceGC
- 大量线程频繁切换,这个时候cpu使用率可能不高
- 高磁盘io、高网络io
- 如果都不是的话,可能是系统资源吃紧或故障,检查磁盘使用、检查内存使用和外挂io设备状态
2.3 高cpu高load
说明系统处于超负荷状态,有2种可能:大量循环、大量序列化或者频繁gc
2.4 低cpu高load
高load低cpu大概率是io问题,也有可能是大量线程频繁切换导致。
- 通过vmstat来查看上下文切换情况。(每秒几w次或几十w次)
- 查看vmstat,查看procs下的b这列(不可中断睡眠),如果不为0说明存在io等待,初步判断是io问题
- 磁盘io:检查top中表示磁盘io的wa的百分比,确认是不是磁盘io导致的
- 网络io:对依赖方的调用任何一个出现比较高的耗时都会增加自身系统的load
- 检查中间件mysql、redis的调用错误日志,mysql可以用show full processlist命令查看线程等待情况,把其中的语句拿出来进行优化
- 检查监控中dubbo、http调用是否存在较高耗时
- 多次打印jstack线程堆栈,查找java.net.SocketInputStream相关的代码
- 资源吃紧或故障
- 检查磁盘使用df- h
- 检查内存使用free -m
- 可用物理内存不足时会发生比较严重的swap,SSD或网络的故障时系统调用会发生比较严重的中断