Linux问题定位命令
1、整体状况
【1】top
使用该命令可以查看系统的CPU、负载等情况
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2014 root 20 0 2653m 28m 10m S 100.1 1.5 8:44.59 java
查看CPU利用率排行第一的进程,可以看到是一个Java程序
load average: 1.00, 0.80, 0.42
右上角是系统的负载情况,分别表示 1分钟、5分钟和15分钟的采样,如果这几个值的和除以3再乘以100%,超过了60%,则表示当前系统负载存在压力
【2】uptime
top
命令的简版
21:09:18 up 15 min, 2 users, load average: 1.00, 0.89, 0.53
该命令主要能够查看机器的负载情况
2、CPU状况
【1】vmstat
语法 vmstat -n 采样时间间隔 采样次数
例如:vmstat -n 2 3
,每2秒采样一次,一共采样3次
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 1645680 18376 153000 0 0 68 2 413 44 39 0 61 0 0
1 0 0 1645600 18376 153000 0 0 0 0 1031 56 50 0 50 0 0
1 0 0 1645600 18376 153000 0 0 0 0 1030 58 50 0 50 0 0
通过该命令可以查看包括CPU在内的一些系统信息
procs:
- r:运行和等待CPU时间片的进程数,数量不要超过总核数的2倍,否则表示系统压力大
- b:等待资源的进程数,包括磁盘I/O等待、网络I/O等待,等
cpu:
- us:用户进程的CPU使用率
- sy:系统进程的CPU使用率
- id:空闲CPU百分比
- wa:等待资源I/O的CPU百分比
如果 us + sy 的值大于80%,则可能存在CPU使用率过高的情况
【2】mpstat
语法 mpstat -P ALL 采样时间间隔 采样次数
例如:mpstat -P ALL 2 3
,每2秒采样一次,一共采样3次
Linux 2.6.32-642.el6.x86_64 (???) 2019年??月??日 _x86_64_ (2 CPU)
21时30分07秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
21时30分09秒 all 50.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 50.00
21时30分09秒 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
21时30分09秒 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
21时30分09秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
21时30分11秒 all 50.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 49.88
21时30分11秒 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
21时30分11秒 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
21时30分11秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
21时30分13秒 all 50.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 50.00
21时30分13秒 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
21时30分13秒 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
平均时间: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
平均时间: all 50.04 0.00 0.00 0.00 0.00 0.00 0.00 0.00 49.96
平均时间: 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均时间: 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
可以看到该机器的CPU是双核的,其中一个(CPU0)的用户使用率(%usr)已经达到了100.00%,而且空闲率(%idle)为0.00%,这说明目前机器的CPU压力很高
【3】pidstat
语法 pidstat -p 进程号 -u 采样间隔 采样次数
例如:
我们通过 ps -ef|grep java
命令,获取到了Java程序的进程号为2014
root 2014 1981 99 20:58 pts/0 00:44:03 java A
再通过 pidstat -p 2014 -u 2 3
,来获取该程序的CPU使用情况
Linux 2.6.32-642.el6.x86_64 (???) 2019年??月??日 _x86_64_ (2 CPU)
21时44分03秒 PID %usr %system %guest %CPU CPU Command
21时44分05秒 2014 100.00 0.00 0.00 100.00 1 java
21时44分07秒 2014 100.00 0.00 0.00 100.00 1 java
21时44分09秒 2014 100.00 0.00 0.00 100.00 1 java
平均时间: 2014 100.00 0.00 0.00 100.00 - java
可以看到该程序目前的CPU使用率达到了100.00%(%usr)
【4】实战高CPU占用率
top
,查看%CPU
使用最高的进程PID
ps -mp 进程ID -o THREAD,tid,time
,查看具体的线程TID
- -m:显示所有的线程
- -o:显示用户指定的格式
- -p 进程ID:显示进程使用CPU的时间
- 将十进制的线程TID,
转换为十六进制
的线程TID,且必须是小写 jstack 进程ID | grep 十六进制线程ID -A显示的行数
,查看指定线程的,前指定行数的堆栈信息
示例:
public class HighCpu {
public static void main(String[] args) {
for (;;) {
}
}
}
问题代码
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3619 root 20 0 2653m 22m 10m S 100.1 1.1 0:10.39 java
【1】top查看进程ID为3619
ps -mp 3619 -o THREAD,tid,time
USER %CPU PRI SCNT WCHAN USER SYSTEM TID TIME
root 98.9 - - - - - - 00:00:25
root 0.0 19 - futex_ - - 3619 00:00:00
root 98.8 19 - - - - 3620 00:00:25
root 0.0 19 - futex_ - - 3621 00:00:00
root 0.0 19 - futex_ - - 3622 00:00:00
root 0.0 19 - futex_ - - 3623 00:00:00
root 0.0 19 - futex_ - - 3624 00:00:00
root 0.0 19 - futex_ - - 3625 00:00:00
root 0.0 19 - futex_ - - 3626 00:00:00
root 0.0 19 - futex_ - - 3627 00:00:00
root 0.0 19 - futex_ - - 3628 00:00:00
root 0.0 19 - futex_ - - 3629 00:00:00
root 0.0 19 - futex_ - - 3630 00:00:00
【2】查看具体的线程ID为3620
【3】转换3620为十六进制,小写,即:e24
jstack 3619 | grep e24 -A50
"main" #1 prio=5 os_prio=0 tid=0x00007f7f24009000 nid=0xe8f runnable [0x00007f7f28d08000]
java.lang.Thread.State: RUNNABLE
at ???.HighCpu.main(HighCpu.java:3)
"VM Thread" os_prio=0 tid=0x00007f7f24073000 nid=0xe92 runnable
"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f7f2401e000 nid=0xe90 runnable
"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f7f24020000 nid=0xe91 runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007f7f240d7000 nid=0xe99 waiting on condition
JNI global references: 5
【4】通过jstack命令,查看线程e24执行的代码的前50行,可以看到问题代码在 HighCpu.java 文件的第3行
3、内存状况
【1】free
语法 free -m
例如:free -m
,使用MB为单位,查看内存的使用情况
total used free shared buffers cached
Mem: 1990 562 1427 1 51 276
-/+ buffers/cache: 234 1756
Swap: 2047 0 2047
可以看到物理内存2GB,已经使用了562MB。交换内存2GB,还未使用
应用程序占用内存 / 物理内存,在20% ~ 70%是合理的
【2】pidstat
语法 pidstat -p 进程号 -r 采样间隔 采样次数
例如:pidstat -p 4526 -r 2 3
,查看4526进程的内存使用情况
Linux 2.6.32-642.el6.x86_64 (???) 2019年??月??日 _x86_64_ (2 CPU)
22时31分18秒 PID minflt/s majflt/s VSZ RSS %MEM Command
22时31分20秒 4526 0.00 0.00 2716884 262204 12.86 java
22时31分22秒 4526 0.00 0.00 2716884 262204 12.86 java
22时31分24秒 4526 271.50 0.00 2716884 299048 14.67 java
平均时间: 4526 90.50 0.00 2716884 274485 13.47 java
可以看到该程序的内存占用率达到了14.67%
4、磁盘状况
【1】df
使用命令df -h
,可以查看磁盘的使用和剩余状况
例如:
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 18G 4.3G 13G 26% /
tmpfs 996M 72K 996M 1% /dev/shm
/dev/sda1 190M 39M 142M 22% /boot
可以看到系统引导区(挂载点是 /boot),一共是190MB,使用了39MB(大约22%),剩余142MB
根目录(挂载点是 /),一共是18GB,使用了4.3GB(大约26%),剩余13GB
【2】iostat
语法 iostat -dkx 采样间隔 采样次数
,可以查看磁盘的I/O状况
- -d:显示设备(磁盘)的使用状况
- -k:以KB为单位显示磁盘的输出
- -x:在输出中包括扩展的磁盘指标
该命令可以搭配lsblk
命令(列出所有的块设备,并且显示它们之间的依赖关系)来使用
例如:lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 200M 0 part /boot
├─sda2 8:2 0 2G 0 part [SWAP]
└─sda3 8:3 0 17.8G 0 part /
例如:iostat -dkx 1 3
,查看当前磁盘的I/O状况
Linux 2.6.32-642.el6.x86_64 (???) 2019年??月??日 _x86_64_ (2 CPU)
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.88 0.52 2.20 0.36 41.71 3.52 35.35 0.00 0.96 0.90 1.32 0.78 0.20
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
需要关注几个参数:
- rkB/s:每秒读取的千兆字节数
- wkB/s:每秒写入的千兆字节数
- await:磁盘响应时间,平均每次设备I/O操作的等待时间(毫秒)。时间越短越好
- %util:统计时间间隔秒中有百分之多少的时间用于I/O操作,即该值 = 设备I/O操作时间 / 统计间隔时间。所以该值暗示了设备的繁忙程度,如果该值是100%,则表示设备已经接近满负荷运行了(如果是多次盘,因为磁盘的并发能力,所以磁盘的使用率未必就达到了瓶颈)
【3】pidstat
语法 pidstat -p 进程ID -d 采样间隔 采样次数
注意:-d参数只能是内核2.6.20 及以后版本才有。可以通过uname -r
来查看内核发行号信息
例如:
2.6.32-642.el6.x86_64
可以看到内核版本是2.6.32
例如:pidstat -p 4969 -d 1 3
Linux 2.6.32-642.el6.x86_64 (???) 2019年??月??日 _x86_64_ (2 CPU)
23时30分41秒 PID kB_rd/s kB_wr/s kB_ccwr/s Command
23时30分42秒 4969 0.00 0.00 0.00 java
23时30分43秒 4969 0.00 0.00 0.00 java
23时30分44秒 4969 0.00 0.00 0.00 java
平均时间: 4969 0.00 0.00 0.00 java
可以查看该进程的每秒读取的千兆字节数(kB_rd/s)和已经完成或将要写入的千兆字节数(kB_wr/s)
5、网络状况
ifstat
需要注意的是该命令并不是Linux系统自带的,需要我们到 官网下载 并编译安装它
最新版本是 v1.1 - 01/01/2004 “The Happy New Year Release”
-rwxr-xr-x. 1 root root 67920 10月 5 23:57 ifstat-1.1.tar.gz
语法 ifstat -a 采样间隔 采样次数
监听所有网络端口,包括回环端口(lo)
例如:ifstat -a 1 3
lo eth0
KB/s in KB/s out KB/s in KB/s out
0.00 0.00 0.06 0.18
0.00 0.00 0.06 0.13
0.00 0.00 0.06 0.13
可以查看eth0网卡的每秒读入量(KB/s in)和读出量(KB/s out)