[TOC]

0x00 性能监控

iostat 命令

描述:Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,该工具对系统的磁盘操作活动进行监视(IO负载);通过iostat方便查看CPU、网卡、tty设备、磁盘、CD-ROM 等等设备的活动情况, 负载信息。

特点:

  • 1.汇报磁盘活动统计情况,同时也会汇报出CPU使用情况
  • 2.同vmstat一样iostat也有一个弱点,就是它不能对某个进程进行深入分析,仅对系统的整体情况进行分析

iostat属于sysstat软件包

1
yum install -y sysstat

命令格式:

1
2
iostat[参数][时间][次数]
iostat [ -c ] [ -d ] [ -h ] [ -N ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ -z ] [ device [...] | ALL ] [ -p [ device [,...] | ALL ] ] [ interval [ count ] ]

命令参数:

1
2
3
4
5
6
7
8
9
10
-C 显示CPU使用情况
-d 显示磁盘使用情况
-k 以 KB 为单位显示
-m 以 M 为单位显示
-N 显示磁盘阵列(LVM) 信息
-n 显示NFS 使用情况
-p[磁盘] 显示磁盘和分区的情况
-t 显示终端和CPU的信息
-x 显示详细信息
-V 显示版本信息

基础示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#1.显示所有设备负载情况
$ iostat
Linux 3.10.0-693.el7.x86_64 (weiyigeek) 04/12/2020 _x86_64_ (16 CPU)
# avg-cpu: %user %nice %system %iowait %steal %idle
# 0.02 0.00 0.01 0.00 0.00 99.96
# Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
# vda 0.34 0.06 8.66 208182 28650151
# scd0 0.00 0.00 0.00 232 0


#cpu属性值说明:
* %user:CPU处在用户模式下的时间百分比。
* %nice:CPU处在带NICE值的用户模式下的时间百分比。
* %system:CPU处在系统模式下的时间百分比。
* %iowait:CPU等待输入输出完成时间的百分比。
* %steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。
* %idle:CPU空闲时间百分比。

#disk属性值说明:
* tps:该设备每秒的传输次数(Indicate the number of transfers per second that were issued to the device.)。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的。
* kB_read/s:每秒从设备(drive expressed)读取的数据量;
* kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
* kB_read:读取的总数据量;
* kB_wrtn:写入的总数量数据量;

* rrqm/s: 每秒进行 merge 的读操作数目。即 rmerge/s
* wrqm/s: 每秒进行 merge 的写操作数目。即 wmerge/s
* r/s: 每秒完成的读 I/O 设备次数。即 rio/s
* w/s: 每秒完成的写 I/O 设备次数。即 wio/s
* rsec/s: 每秒读扇区数。即 rsect/s
* wsec/s: 每秒写扇区数。即 wsect/s
* rkB/s: 每秒读K字节数。是 rsect/s 的一半,因为每扇区大小为512字节。
* wkB/s: 每秒写K字节数。是 wsect/s 的一半。
* avgrq-sz: 平均每次设备I/O操作的数据大小 (扇区)。
* avgqu-sz: 平均I/O队列长度。
* await: 平均每次设备I/O操作的等待时间 (毫秒)。
* svctm: 平均每次设备I/O操作的服务时间 (毫秒)。
* %util: 一秒中有百分之多少的时间用于 I/O 操作,即被io消耗的cpu百分比

  • 备注:如果%iowait的值过高,表示硬盘存在I/O瓶颈,%idle值高,表示CPU较空闲,如果%idle值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量。%idle值如果持续低于10,那么系统的CPU处理能力相对较低,表明系统中最需要解决的资源是CPU

  • 备注:如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明I/O 队列太长,io响应太慢,则需要进行必要优化。如果avgqu-sz比较大,也表示有当量io在等待

  • 备注:上面的例子中,我们可以看到磁盘vda以及它的各个分区的统计数据,当时统计的磁盘总TPS是22.73,下面是各个分区的TPS。(因为是瞬间值,所以总TPS并不严格等于各个分区TPS的总和)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#实例2:定时显示所有信息(显示3条数据且两秒刷新一次)
$iostat 2 3
$iostat -c 2 3 #CPU

#实例3:显示指定磁盘信息(上面我只有一块硬盘)
$ iostat -d vda
$ iostat -d 1
Linux 5.4.0-47-generic (weiyigeek-104) 09/14/2020 _x86_64_ (4 CPU)
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
# dm-0 3.92 1.87 18.12 0.00 474009 4599964 0
# loop0 0.00 0.00 0.00 0.00 338 0 0
# loop1 0.01 0.01 0.00 0.00 1733 0 0
# loop2 0.00 0.00 0.00 0.00 1074 0 0
# loop3 0.00 0.00 0.00 0.00 1079 0 0
# loop4 0.05 0.05 0.00 0.00 12335 0 0
# loop5 0.00 0.00 0.00 0.00 336 0 0
# loop6 0.00 0.00 0.00 0.00 4 0 0
# sda 3.02 1.89 18.12 0.00 480510 4600068 0
# sdb 0.00 0.02 0.00 0.00 4868 4 0

#实例4:以M为单位显示tty和Cpu信息
$iostat -t -m

#实例5:查看TPS和吞吐量信息每一秒刷新共十次
$iostat -d -k 1 10
# Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
# vda 0.34 0.06 8.66 208258 28665138
# scd0 0.00 0.00 0.00 232 0

#实例6:-x选择获取更多统计信息查看设备使用率(%util)、响应时间(await)
iostat -d -x -k 1 10
# Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
# vda 0.00 0.03 0.00 0.34 0.06 8.66 50.60 0.02 62.38 2.32 62.83 1.35 0.05
# scd0 0.00 0.00 0.00 0.00 0.00 0.00 6.54 0.00 0.51 0.51 0.00 0.51 0.00
* 一般idle小于70%即未正常状态
* await 与 svctm 的参数来参考,如果差的过高就一定有 IO 的问题。
* svctm 的大小一般和磁盘性能有关,CPU/内存的负荷也会对其有影响,请求过多也会间接导致 svctm 的增加
* avgqu-sz 调优时需要注意的地方 : `avgqu-sz × ( r/s or w/s ) = rsec/s or wsec/s`
* 队列长度(avgqu-sz)也可作为衡量系统 I/O 负荷的指标,但由于 avgqu-sz 是按照单位时间的平均值,所以不能反映瞬间的 I/O 洪水。

#示例7.以人类的方式显示数据

补充说明:

  • r/s+w/s 类似于交款人的总数
  • 平均队列长度(avgqu-sz)类似于单位时间里平均排队人的个数
  • 平均服务时间(svctm)类似于收银员的收款速度
  • 平均等待时间(await)类似于平均每人的等待时间
  • 平均I/O数据(avgrq-sz)类似于平均每人所买的东西多少
  • I/O 操作率 (%util)类似于收款台前有人排队的时间比例
  • 设备IO操作:总IO(io)/s = r/s(读) +w/s(写) =1.46 + 25.28=26.74
  • 平均每次设备I/O操作只需要0.36毫秒完成,现在却需要10.57毫秒完成,因为发出的请求太多(每秒26.74个),假如请求时同时发出的,可以这样计算平均等待时间: 平均等待时间=单个I/O服务器时间*(1+2+…+请求总数-1)/请求总数;
  • 每秒发出的I/0请求很多,但是平均队列就4,表示这些请求比较均匀,大部分处理还是比较及时。


lsof 命令 - 列出Linux所有打开的文件信息(等同于查看Linux各种信息排查故障的利器)

描述:list open files是一个列出当前系统打开文件的工具用于查看你进程开打的文件/的进程,进程打开的端口(TCP、UDP),是十分方便的系统监视工具,因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,文件描述符为应用程序与基础操作系统之间的交互提供了通用接口;

在linux环境下任何事物都以文件的形式存在包括但不限于普通文件/目录/网络文件系统的文件/字符或设备文件/(函数)共享库/管道、命名管道/符号链接/网络文件(例如:NFS file、网络socket,unix域名socket)/还有其它类型的文件;

  • 1.普通文件
  • 2.目录
  • 3.网络文件系统的文件
  • 4.字符或设备文件
  • 5.(函数)共享库
  • 6.管道,命名管道
  • 7.符号链接
  • 8.网络文件(例如:NFS file、网络socket,unix域名socket)
  • 9.还有其它类型的文件,等等

特点&功能:

  • root用户执行 (lsof命令需要访问核心内存和各种文件)
  • 恢复误删除但还在内存中的文件
  • 对系统监测以及排错

语法命令参数格式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#语法
lsof [参数][文件]
lsof [-?abhlnNoOPRtUvVX] [+|-c c] [+|-d s] [+D D] [+|-f[gG]] [+|-e s]
[-F [f]] [-g [s]] [-i [i]] [+|-L [l]] [+m [m]] [+|-M] [-o [o]] [-p s]
[+|-r [t]] [-s [p:s]] [-S [t]] [-T [t]] [-u s] [+|-w] [-x [fl]] [-Z [Z]] [--] [names]

#参数
-a:列出打开文件存在的进程;
-c<进程名>:列出指定进程所打开的文件;
-g:列出GID号进程详情;
-d<文件号>:列出占用该文件号的进程;
+d<目录>:列出目录下被打开的文件;
+D<目录>:递归列出目录下被打开的文件;
-n<目录>:列出使用NFS的文件;
-i<条件>:列出符合条件的进程。(4、6、协议、:端口、 @ip )
-p<进程号>:列出指定进程号所打开的文件;
+L<fd>: 查找为链接的文件
-u:列出UID号进程详情;
-h:显示帮助信息;
-v:显示版本信息。

关键字描述:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#文件描述符列表FD
* cwd:表示current work dirctory,#即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
* txt:#该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
* lnn:#library references (AIX);
* er:#FD information error (see NAME column);
* jld:#jail directory (FreeBSD);
* ltx:#shared library text (code and data);
* mxx :#hex memory-mapped type number xx.
* m86:#DOS Merge mapped file;
* mem:#memory-mapped file;
* mmap:#memory-mapped device;
* pd:#parent directory;
* rtd:#root directory;
* tr:#kernel trace file (OpenBSD);
* v86 #VP/ix mapped file;
* 0:#表示标准输出
* 1:#表示标准输入
* 2:#表示标准错误


#一般在标准输出、标准错误、标准输入后还跟着文件状态模式:
* u:#表示该文件被打开并处于读取/写入模式。
* r:#表示该文件被打开并处于只读模式。
* w:#表示该文件被打开并处于写入模式。
* 空格:#表示该文件的状态模式为unknow,且没有锁定。
* -:#表示该文件的状态模式为unknow,且被锁定。


#同时在文件状态模式后面,还跟着相关的锁:
* N:for a Solaris NFS lock of unknown type;
* r:for read lock on part of the file;
* R:for a read lock on the entire file;
* w:for a write lock on part of the file;(文件的部分写锁)
* W:for a write lock on the entire file;(整个文件的写锁)
* u:for a read and write lock of any length;
* U:for a lock of unknown type;
* x:for an SCO OpenServer Xenix lock on part of the file;
* X:for an SCO OpenServer Xenix lock on the entire file;
* space:if there is no lock.


#文件类型:TYEP
* DIR:表示目录。
* CHR:表示字符类型。
* BLK:块设备类型。
* UNIX: UNIX 域套接字。
* FIFO:先进先出 (FIFO) 队列。
* IPv4:网际协议 (IP) 套接字。
* DEVICE:指定磁盘的名称

SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称

实际案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#示例1.lsof命令输出解释
$lsof
command PID USER FD type DEVICE SIZE NODE NAME
# init 1 root txt REG 8,2 43496 6121706 /sbin/init
# sshd 6058 root 3u IPv4 33503 0t0 TCP localhost.localdomain:ssh->10.19.172.88:51165 (ESTABLISHED)
#lsof输出各列信息的意义如下:
* COMMAND:进程的名称
* PID:进程标识符
* PPID:父进程标识符(需要指定-R参数)
* FD:文件描述符,应用程序通过文件描述符识别该文件。
* USER:进程所有者
* PGID:进程所属组


#示例2.查找未链接的文件
lsof +L 1 | head
lsof +L 2 | head
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
# systemd 1 root txt REG 253,0 1620416 1 100755256 /usr/lib/systemd/systemd
# systemd 1 root mem REG 253,0 20112 1 31765 /usr/lib64/libuuid.so.1.3.0
# systemd 1 root mem REG 253,0 265624 1 31772 /usr/lib64/libblkid.so.1.1.0


#示例3.查找某个文件相关的进程
lsof /usr/sbin/sshd
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# sshd 9427 root txt REG 253,1 852856 51767854 /usr/sbin/sshd
# sshd 28834 root txt REG 253,1 852856 51767854 /usr/sbin/sshd
# sshd 28838 root txt REG 253,1 852856 51767854 /usr/sbin/sshd


#示例4.递归查找某个目录中所有打开的文件(即被应用程序调用的文件)
lsof +D /usr/sbin/
lsof | grep '/usr/sbin/' #不使用+D选项,遍历查看某个目录的所有文件信息的方法
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# rsyslogd 2772 root txt REG 253,1 663864 50668535 /usr/sbin/rsyslogd
# chronyd 3525 chrony txt REG 253,1 252512 50668522 /usr/sbin/chronyd
# acpid 3624 root txt REG 253,1 53560 50736074 /usr/sbin/acpid


#实例5:列出某个用户打开的文件信息
lsof -u root
lsof -u weiyigeek |more #单个用户
lsof -u root,weiyigeel #多个用户
lsof -u ^root | more # 列出除root用户外的所有用户打开的文件
# COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# dbus-daem 5113 dbus cwd DIR 253,0 250 64 /
# dbus-daem 5113 dbus rtd DIR 253,0 250 64 /
# dbus-daem 5113 dbus txt REG 253,0 223320 100767271 /usr/bin/dbus-daemon
lsof -g 5555 #某个用户组所打开的文件信息


#示例6.查看关联文件(查找某个程序打开的所有文件)
lsof -c 进程名
lsof -c sshd
lsof | grep mysql
lsof -c mysql -c apache #列出多个进程多个打开的文件信息
# sshd 6058 root 0u CHR 1,3 0t0 5334 /dev/null
# sshd 6058 root 1u CHR 1,3 0t0 5334 /dev/null
# sshd 6058 root 2u CHR 1,3 0t0 5334 /dev/null
# sshd 6058 root 3u IPv4 33503 0t0 TCP localhost.localdomain:ssh->127.0.0.1:51165 (ESTABLISHED)


#实例7:列出某个用户以及某个进程所打开的文件信息
lsof -u test -c mysql #用户与进程可相关,也可以不相关


#示例8.查看进程所打开的端口及文件
lsof -p pid
lsof -p 22 #通过某个进程号显示该进行打开的文件
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# md 22 root cwd DIR 253,0 250 64 /
# md 22 root rtd DIR 253,0 250 64 /
# md 22 root txt unknown /proc/22/exe

lsof -p ^1 #列出除了某个进程号,其他进程号所打开的文件信息
lsof -p 1,2,3 #列出多个进程号对应的文件信息


#示例9.获取进程打开端口的信息
lsof -i #列出端口号占用的进程
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# chronyd 682 chrony 5u IPv4 14710 0t0 UDP localhost:323
# chronyd 682 chrony 6u IPv6 14711 0t0 UDP localhost:323
# dhclient 996 root 6u IPv4 16109 0t0 UDP *:bootpc
# sshd 1202 root 3u IPv4 20035 0t0 TCP *:EtherNet/IP-1 (LISTEN)
# sshd 1202 root 4u IPv6 20037 0t0 TCP *:EtherNet/IP-1 (LISTEN)
# master 1203 root 13u IPv4 18762 0t0 TCP localhost:smtp (LISTEN)
# master 1203 root 14u IPv6 18763 0t0 TCP localhost:smtp (LISTEN
lsof -i :53
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# systemd-r 538 systemd-resolve 12u IPv4 13925 0t0 UDP localhost:domain
# systemd-r 538 systemd-resolve 13u IPv4 13926 0t0 TCP localhost:domain (LISTEN)
lsof -i :22 #指定服务或者端口,查看一下80端口的进程
# sshd 5460 root 3u IPv4 31918 0t0 TCP *:ssh (LISTEN)
# sshd 5460 root 4u IPv6 31920 0t0 TCP *:ssh (LISTEN)
# sshd 5971 root 3u IPv4 32781 0t0 TCP localhost.localdomain:ssh->127.0.0.1:51147 (ESTABLISHED)
lsof -i :ssh #指定服务或者端口
#列出谁在使用某个特定的udp端口以及特定的tcp端口
lsof -i tcp:80
lsof -i udp:68
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# dhclient 3966 root 6u IPv4 30736 0t0 UDP *:bootpc
lsof -i udp -i tcp #列出所有TCP/UDP网络连接
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# chronyd 5116 chrony 1u IPv4 28218 0t0 UDP localhost:323
# chronyd 5116 chrony 2u IPv6 28219 0t0 UDP localhost:323


#实例10:列出某个用户的所有活跃的网络端口
lsof -a -u root -i
lsof -a -u root -i -n #将服务名称变成端口


#实例11:列出所有网络文件系统
lsof -N

#实例12:根据文件描述列出对应的文件信息(FD)
lsof -d txt
lsof -d 1
lsof -d 2
lsof -d 2-3 #根据文件描述范围列出文件信息
#0表示标准输入,1表示标准输出,2表示标准错误,从而可知:所以大多数应用程序所打开的文件的 FD 都是从 3 开始


#实例13.列出COMMAND列中包含字符串" sshd",且文件描符的类型为txt的文件信息
lsof -c sshd -a -d txt
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# sshd 9427 root txt REG 253,1 852856 51767854 /usr/sbin/sshd
# sshd 28834 root txt REG 253,1 852856 51767854 /usr/sbin/sshd
# sshd 28838 root txt REG 253,1 852856 51767854 /usr/sbin/sshd


#实例14:列出被进程号为9427的进程所打开的所有IPV4 network files
lsof -i 4 -a -p 9427
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
sshd 9427 root 3u IPv4 11551516 0t0 TCP *:EtherNet/IP-1 (LISTEN)

#实例15:列出目前连接主机peida.linux上端口为:20,21,22,25,53,80相关的所有文件信息,且每隔3秒不断的执行lsof指令
lsof -i @weiyigeek:20,21,22,25,53,80 -r 3

WeiyiGeek.lsof目录递归

WeiyiGeek.lsof目录递归


系统资源查看

lsmem 命令 - 列出内存范围与在线状态

描述:列出可用内存的范围与他们的在线状态,所列出的存储块对应于在sysfs存储器框图表示。该命令还示出了存储器块大小与内存在在线和离线状态的量。

基础示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$lsmem
RANGE SIZE STATE REMOVABLE BLOCK
0x0000000000000000-0x0000000007ffffff 128M online 否 0
0x0000000008000000-0x0000000027ffffff 512M online 是 1-4
0x0000000028000000-0x0000000037ffffff 256M online 否 5-6
0x0000000038000000-0x000000003fffffff 128M online 是 7
0x0000000040000000-0x000000004fffffff 256M online 否 8-9
0x0000000050000000-0x0000000067ffffff 384M online 是 10-12
0x0000000068000000-0x00000000bfffffff 1.4G online 否 13-23
0x0000000100000000-0x0000000117ffffff 384M online 是 32-34
0x0000000118000000-0x000000013fffffff 640M online 否 35-39

Memory block size: 128M
Total online memory: 4G
Total offline memory: 0B


lsns 命令 - 列出当前名称空间信息

描述:列出所有当前访问的命名空间或对给定的命名空间信息。命名空间标识符是inode编号。

基础示例:

1
2
3
4
5
6
7
8
9
10
11
$lsns
NS TYPE NPROCS PID USER COMMAND
4026531836 pid 126 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 22
4026531837 user 126 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 22
4026531838 uts 126 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 22
4026531839 ipc 126 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 22
4026531840 mnt 123 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 22
4026531856 mnt 1 28 root kdevtmpfs
4026531956 net 126 1 root /usr/lib/systemd/systemd --switched-root --system --deserialize 22
4026532156 mnt 1 682 chrony /usr/sbin/chronyd
4026532157 mnt 1 766 root /usr/sbin/NetworkManager --no-daemon


系统优化