sysstat是一个linux性能工具,用来监控和分析系统的性能,以下案例中会用到这个包的2个命令mpstat和pidstat。
# -P ALL 表示监控所有 CPU,后面数字 5 表示间隔 5 秒后输出一组数据
mpstat -P ALL 5
Linux 4.18.0-147.5.1.el8_1.x86_64 (service) 2021年06月17日 _x86_64_ (4 CPU)
11时02分41秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
11时02分46秒 all 53.29 0.00 5.72 0.00 1.22 2.28 0.00 0.00 0.00 37.49
11时02分46秒 0 8.69 0.00 15.56 0.00 0.61 0.20 0.00 0.00 0.00 74.95
11时02分46秒 1 99.40 0.00 0.00 0.00 0.60 0.00 0.00 0.00 0.00 0.00
11时02分46秒 2 2.92 0.00 7.52 0.00 3.34 9.19 0.00 0.00 0.00 77.04
11时02分46秒 3 99.60 0.00 0.00 0.00 0.40 0.00 0.00 0.00 0.00 0.00
参数 | 释义 |
---|---|
CPU | 处理器ID |
%usr | 在internal时间段里,用户态的CPU时间(%),不包含 nice值为负进程 sr/total*100 |
%nice | 在internal时间段里,nice值为负进程的CPU时间(%) nice/total*100 |
%sys | 在internal时间段里,CPU时间(%) system/total*100 |
%iowait | 在internal时间段里,硬盘IO等待(%) iowait/total*100 |
%irq | 在internal时间段里,硬中断时间(%) irq/total*100 |
%soft | 在internal时间段里,软中断时间(%) softirq/total*100 |
%steal | 显示虚拟机管理器在服务另一个虚拟处理器时虚拟CPU处在非自愿等待下花费时间的百分比 steal/total*100 |
%guest | 显示运行虚拟处理器时CPU花费时间的百分比 guest/total*100 |
%gnice | gnice/total*100 |
%idle | 在internal时间段里,CPU除去等待磁盘IO操作外的因为任何原因而空闲的时间闲置时间(%) idle/total*100 |
pidstat -t 5
19时40分33秒 UID PID cswch/s nvcswch/s Command
19时40分38秒 0 9 1.00 0.00 ksoftirqd/0
19时40分38秒 0 10 30.94 0.00 rcu_sched
参数 | 释义 |
---|---|
UID | 用户id |
PID | 进程ID |
%usr | 进程在用户空间占用cpu的百分比 |
%system | 进程在内核空间占用cpu的百分比 |
%guest | 进程在虚拟机占用cpu的百分比 |
%wait | 进程在等待CPU的时间百分比 |
%CPU | 进程占用cpu的百分比 |
CPU | 处理进程的cpu编号 |
%Command | 当前进程对应的命令 |
查看平均负载的变化情况:
watch -d uptime
vmstat 是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分 析 CPU 上下文切换和中断的次数。
[root@ ~]# vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
2 0 101120 2083104 1044 692872 0 0 0 0 37327 57872 3 8 89 0 0
需要特别关注的四列内容:
perf 是 Linux 2.6.31 以后内置的性能分析工具。它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。
perf top -g
Samples: 785K of event 'cpu-clock:pppH', 4000 Hz, Event count (approx.): 8358801205 lost: 0/0 drop: 0/0
Overhead Shared Object Symbol
32.52% 0.04% imsocket [.] imsocketio/events.ListeningClose
22.03% 2.86% [kernel] [k] __softirqentry_text_start
....
输出结果中,第一行包含三个数据,分别是采样数(Samples)、事件类型(event)和 事件总数量(Event count)。比如这个例子中,perf 总共采集了 785K CPU 时钟事件,而总事件数则为 8358801205。
另外,采样数需要我们特别注意。如果采样数过少(比如只有十几个),那下面的排序和 百分比就没什么实际参考价值了。
再往下看是一个表格式样的数据,每一行包含四列,分别是:
接着再来看第二种常见用法,也就是 perf record 和 perf report。 perf top 虽然实时展 示了系统的性能信息,但它的缺点是并不保存数据,也就无法用于离线或者后续的分析。 而 perf record 则提供了保存数据的功能,保存后的数据,需要你用 perf report 解析展示。
perf record -g
dstat 是一个新的性能工具,它吸收了 vmstat、iostat、ifstat 等几种工具的优点, 可以同时观察系统的 CPU、磁盘 I/O、网络以及内存使用情况。
yum install -y dstat
安装完后就可以使用了,dstat非常强大,可以实时的监控cpu、磁盘、网络、IO、内存等使用情况。
直接使用dstat,默认使用的是-cdngy参数,分别显示cpu、disk、net、page、system信息,默认是1s显示一条信息。可以在最后指定显示一条信息的时间间隔,如dstat 5是没5s显示一条,dstat 5 10表示没5s显示一条,一共显示10条。
# dstat
----total-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai stl| read writ| recv send| in out | int csw
0 0 99 0 0| 0 0 |5266B 3868B| 0 0 |1283 2306
0 1 99 0 0| 0 0 |4860B 1846B| 0 0 |1384 2488
0 0 99 0 0| 0 0 |4798B 4753B| 0 0 |1255 2293
0 0 99 0 0| 0 23k|4799B 1754B| 0 0 |1279 2345
0 0 100 0 0| 0 0 |4799B 1762B| 0 0 |1189 2174
0 0 99 0 0| 0 0 |5075B 2072B| 0 0 |1274 2310
3 1 96 0 0| 0 0 |5348B 2294B| 0 0 |1567 2477
2 1 97 0 0| 0 0 |5010B 2069B| 0 0 |1510 2424
0 0 99 0 0| 0 0 |5075B 1941B| 0 0 |1257 2324
0 0 99 0 0| 0 0 |4799B 1754B| 0 0 |1267 2315
0 0 99 0 0| 0 0 |4865B 1886B| 0 0 |1260 2274
下面对显示出来的部分信息作一些说明:
dstat [-afv] [options…] [delay [count]]
如想监控swap,process,sockets,filesystem并显示监控的时间:
dstat -tsp --socket --fs
----system---- ----swap--- ---procs--- --------sockets--------- --filesystem-
time | used free|run blk new|tot tcp udp raw frg |files inodes
05-07 16:04:08| 68M 4028M| 0 0 |355 99 4 0 0 | 3616 87574
05-07 16:04:09| 68M 4028M|0.5 0 1.0|355 99 4 0 0 | 3648 87580
05-07 16:04:10| 68M 4028M| 0 0 0.5|356 100 4 0 0 | 3680 87586
05-07 16:04:11| 68M 4028M| 0 0 0|356 100 4 0 0 | 3680 87586
05-07 16:04:12| 68M 4028M| 0 0 0|356 100 4 0 0 | 3680 87586
sar 是一个系统活动报告工具,既可以实时查看系统的当前活动,又可以配置保存和报 告历史统计数据。
# -n DEV 表示显示网络收发的报告,间隔 1 秒输出一组数据
sar-n DEV 1
Linux 4.18.0-147.5.1.el8_1.x86_64 (service) 2021年07月02日 _x86_64_ (2 CPU)
15时09分17秒 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
15时09分18秒 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15时09分18秒 eth0 15542.00 7773.00 910.68 444.02 0.00 0.00 0.00 0.00
15时09分18秒 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
15时09分19秒 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15时09分19秒 eth0 15541.00 7771.00 910.61 440.28 0.00 0.00 0.00 0.00
15时09分19秒 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
15时09分20秒 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15时09分20秒 eth0 15202.00 7602.00 890.75 431.15 0.00 0.00 0.00 0.00
15时09分20秒 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
15时09分21秒 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15时09分21秒 eth0 15565.00 7784.00 912.00 441.44 0.00 0.00 0.00 0.00
对于 sar 的输出界面,我先来简单介绍一下,从左往右依次是:
hping3 是一个可以构造 TCP/IP 协议数据包的工具,可以对系统进行安全审计、防火墙 测试等。
# -S 参数表示设置 TCP 协议的 SYN(同步序列号),-p 表示目的端口为 80
# -i u100 表示每隔 100 微秒发送一个网络帧
# 注:如果你在实践过程中现象不明显,可以尝试把 100 调小,比如调成 10 甚至 1 4
hping3 -S -p 80 -i u100 192.168.0.30
tcpdump 是一个常用的网络抓包工具,常用来分析各种网络问题。
proc 文件系统。它是一种内核空间和用户空间进行通信的机制,可以用来查看内核的数据结构,或者用来动态修改内核的配置:
在实际工作中,偶尔会遇到系统的CPU使用率和系统平均负载很高,但却找不到高CPU的应用;
产生这个问题的原因:进程有可能在不断的崩溃、重启
通过uptime发现系统负载很高,但是通过top,mpstat,pidstat,perf等工具很难发现是什么进程导致了系统负载和CPU使用率很高;
注:通过上面工具的判断,即不是CPU密集型,也不存在IO等待,也不存在进程、线程争用的情况
execsnoop-专门用于为追踪短时进程(瞬时进程)设计的工具;
它通过 ftrace 实时监控进程的 exec() 行为,并输出短时进程的基本信息,包括进程 PID、父进程 PID、命令行参数以及执行的结果
strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。
来查看程式运行所需的共享库,常用来解决程式因缺少某个库文件而不能运行的一些问题。
查看test程序运行所依赖的库:
ldd test
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00000039a7e00000)
libm.so.6 => /lib64/libm.so.6 (0x0000003996400000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000039a5600000)
libc.so.6 => /lib64/libc.so.6 (0x0000003995800000)
/lib64/ld-linux-x86-64.so.2 (0x0000003995400000)
此命令可显示每个进程的栈跟踪。pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack 来确定进程挂起的位置。此命令允许使用的唯一选项是要检查的进程的 PID。
这个命令在排查进程问题时非常有用,比如我们发现一个服务一直处于work状态(如假死状态,好似死循环),使用这个命令就能轻松定位问题所在;可以在一段时间内,多执行几次pstack,若发现代码栈总是停在同一个位置,那个位置就需要重点关注,很可能就是出问题的地方;
[root@webim-service-mq ~]# pstack 23664
Thread 7 (LWP 23832):
#0 runtime.futex () at /usr/local/go/src/runtime/sys_linux_amd64.s:580
#1 0x0000000000432306 in runtime.futexsleep (addr=0xc000261950, val=0, ns=-1) at /usr/local/go/src/runtime/os_linux.go:44
#2 0x000000000040c17f in runtime.notesleep (n=0xc000261950) at /usr/local/go/src/runtime/lock_futex.go:159
#3 0x000000000043b7f9 in runtime.mPark () at /usr/local/go/src/runtime/proc.go:1340
#4 0x000000000043cdf2 in runtime.stopm () at /usr/local/go/src/runtime/proc.go:2257
#5 0x000000000043e32e in runtime.findrunnable (gp=0xc000033000, inheritTime=false) at /usr/local/go/src/runtime/proc.go:2916
#6 0x000000000043f677 in runtime.schedule () at /usr/local/go/src/runtime/proc.go:3125
#7 0x000000000043fbfd in runtime.park_m (gp=0xc000083380) at /usr/local/go/src/runtime/proc.go:3274
#8 0x0000000000469bbb in runtime.mcall () at /usr/local/go/src/runtime/asm_amd64.s:327
#9 0x000000c00020fdc0 in ?? ()
#10 0x0000000000000000 in ?? ()
Thread 6 (LWP 23669):
ipcs是Linux下显示进程间通信设施状态的工具。可以显示消息队列、共享内存和信号量的信息。对于程序员非常有用,普通的系统管理员一般用不到此指令。
查看系统使用的IPC资源
[root@# ~]# ipcs
--------- 消息队列 -----------
键 msqid 拥有者 权限 已用字节数 消息
------------ 共享内存段 --------------
键 shmid 拥有者 权限 字节 连接数 状态
--------- 信号量数组 -----------
键 semid 拥有者 权限 nsems
0x002fa327 0 root 600 2
分别查询IPC资源:
# ipcs -m 查看系统使用的IPC共享内存资源
# ipcs -q 查看系统使用的IPC队列资源
# ipcs -s 查看系统使用的IPC信号量资源
free工具用来查看系统可用内存:
[root@webim-service-mq ~]# free
total used free shared buff/cache available
Mem: 3871192 1210960 1027116 508 1633116 2392104
Swap: 4194300 69120 4125180
free的输出一共有2行,第2行为交换区的信息,分别是交换的总量(total),使用量(used)和有多少空闲的交换区(free),这个比较清楚,不说太多。
可以看到,free 输出的是一个表格,其中的数值都默认以字节为单位。表格总共有两行 六列,这两行分别是物理内存 Mem 和交换分区 Swap 的使用情况,而六列中,每列数据 的含义分别为:
这里尤其注意一下,最后一列的可用内存 available 。available 不仅包含未使用内存,还 包括了可回收的缓存,所以一般会比未使用内存更大。不过,并不是所有缓存都可以回收,因为有些缓存可能正在使用中。
iostat是I/O statistics(输入/输出统计)的缩写,用来动态监视系统的磁盘操作活动。
iostat[参数][时间][次数]
通过iostat方便查看CPU、网卡、tty设备、磁盘、CD-ROM 等等设备的活动情况, 负载信息。
iostat
Linux 4.18.0-147.5.1.el8_1.x86_64 (webim-service-mq) 2021年07月05日 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
21.50 0.01 18.61 0.01 0.00 59.88
Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn
vda 0.55 0.25 17.46 2416716 168716452
cpu属性值说明:
注:如果%iowait的值过高,表示硬盘存在I/O瓶颈,%idle值高,表示CPU较空闲,如果%idle值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量。%idle值如果持续低于10,那么系统的CPU处理能力相对较低,表明系统中最需要解决的资源是CPU。
disk属性值说明:
注:如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明I/O 队列太长,io响应太慢,则需要进行必要优化。如果avgqu-sz比较大,也表示有当量io在等待。
cachestat:提供了整个操作系统缓存的读写命中情况。
cachetop:提供了每个进程的缓存命中情况。
这两个工具都是 bcc 软件包的一部分,它们基于 Linux 内核的 eBPF(extended Berkeley Packet Filters)机制,来跟踪内核中管理的缓存,并输出缓存的使用和命中情况。
yum install -y bcc-tools
#操作完这些步骤,bcc 提供的所有工具就都安装到 /usr/share/bcc/tools 这个目录中了。不过,bcc 软件包默认不会把这些工具配置到系统的 PATH 路径中,所以得自己手动配置:
# 配置 PATH 路径
export PATH=$PATH:/usr/share/bcc/tools
配置完,就可以运行 cachestat 和 cachetop 命令了。比如,下面就是一个 cachestat 的运行界面,它以 1 秒的时间间隔,输出了 3 组缓存统计数据:
cachestat 1 3
HITS MISSES DIRTIES HITRATIO BUFFERS_MB CACHED_MB
0 0 0 0.00% 2 2114
0 0 0 0.00% 2 2114
5690 0 0 100.00% 2 2114
可以看到,cachestat 的输出其实是一个表格。每行代表一组数据,而每一列代表不同的缓存统计指标。这些指标从左到右依次表示:
我得这个版本没有显示总的io数
接下来再来看一个 cachetop 的运行界面:
cachetop
14:13:41 Buffers MB: 2 / Cached MB: 2129 / Sort: HITS / Order: descending
PID UID CMD HITS MISSES DIRTIES READ_HIT% WRITE_HIT%
60894 www php 5505 0 0 100.0% 0.0%
60934 www supervisord 1370 0 0 100.0% 0.0%
60934 www php 1111 0 0 100.0% 0.0%
它的输出跟 top 类似,默认按照缓存的命中次数(HITS)排序,展示了每个进程的缓存命 中情况。具体到每一个指标,这里的 HITS、MISSES 和 DIRTIES ,跟 cachestat 里的含义一样,分别代表间隔时间内的缓存命中次数、未命中次数以及新增到缓存中的脏页数。
而 READ_HIT 和 WRITE_HIT ,分别表示读和写的缓存命中率。
pcstat 是一个基于 Go 语言开发的工具,所以安装它之前,首先应该安装 Go 语言
go get github.com/tobert/pcstat/pcstat
全部安装完成后,你就可以运行 pcstat 来查看文件的缓存情况了。比如,下面就是一个 pcstat 运行的示例,它展示了 /bin/ls 这个文件的缓存情况:
pcstat /bin/ls
+---------+----------------+------------+-----------+---------+
| Name | Size (bytes) | Pages | Cached | Percent |
|---------+----------------+------------+-----------+---------|
| /bin/ls | 157376 | 39 | 0 | 000.000 |
+---------+----------------+------------+-----------+---------+
这个输出中,Cached 就是 /bin/ls 在缓存中的大小,而 Percent 则是缓存的百分比。你看到它们都是 ,这说明 /bin/ls 并不在缓存中。
接着,如果你执行一下 ls 命令,再运行相同的命令来查看的话,就会发现 /bin/ls 都在缓存中了:
ls
pcstat /bin/ls
+---------+----------------+------------+-----------+---------+
| Name | Size (bytes) | Pages | Cached | Percent |
|---------+----------------+------------+-----------+---------|
| /bin/ls | 157376 | 39 | 13 | 033.333 |
+---------+----------------+------------+-----------+---------+
memleak 可以跟踪系统或 指定进程的内存分配、释放请求,然后定期输出一个未释放内存和相应调用栈的汇总情况 (默认 5 秒)。
当然,memleak 是 bcc 软件包中的一个工具,我们一开始就装好了,执行/usr/share/bcc/tools/memleak 就可以运行它。
# -a 表示显示每个内存分配请求的大小以及地址
# -p 指定案例应用的 PID 号
/usr/share/bcc/tools/memleak -p 23664 -a
iostat 是最常用的磁盘 I/O 性能观测工具,它提供了每个磁盘的使用率、IOPS、吞吐量等 各种常见的性能指标,当然,这些指标实际上来自 /proc/diskstats。
iostat 的输出界面如下
# -d -x 表示显示所有磁盘 I/O 的指标
iostat -d -x 1
Linux 4.18.0-147.5.1.el8_1.x86_64 (webim-service-mq) 2021年07月29日 _x86_64_ (4 CPU)
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
vda 0.01 0.56 0.47 23.48 0.00 0.07 3.77 11.71 14.87 37.98 0.02 38.50 42.24 0.37 0.02
Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util
vda 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 0.00 0.00
从这里可以看到,iostat 提供了非常丰富的性能指标。第一列的 Device 表示磁盘设备的名字,其他各列指标,虽然数量较多,但是每个指标的含义都很重要。为了方便你理 解,我把它们总结成了一个表格。
这些指标中,要注意:
在观测指标时,也别忘了结合请求的大小( rareq-sz 和 wareq-sz)一起分析。
除了每块磁盘的 I/O 情况,每个进程的 I/O 情况也是我们需要关注的重点。
上面提到的 iostat 只提供磁盘整体的 I/O 性能数据,缺点在于,并不能知道具体是哪些进程在进行磁盘读写。要观察进程的 I/O 情况,还可以使用 pidstat 和 iotop 这两个工具。
pidstat 是我们的老朋友了,这里我就不再啰嗦它的功能了。给它加上 -d 参数,你就可以 看到进程的 I/O 情况,如下所示:
pidstat -d 1
17时24分39秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
17时24分44秒 0 266 0.00 0.80 0.00 jbd2/vda1-8
17时24分44秒 0 504 0.00 12.80 0.00 jbd2/vdb-8
17时24分44秒 27 1387 0.00 0.80 0.00 mysqld
17时24分44秒 997 8908 0.00 1.60 0.00 nginx
17时24分44秒 1000 25621 0.00 14.40 0.00 php-fpm
17时24分44秒 1000 26288 0.00 17.60 0.00 php-fpm
从 pidstat 的输出你能看到,它可以实时查看每个进程的 I/O 情况,包括下面这些内容。
iotop。它是一个类似于 top 的工具,你可以按照 I/O 大小对进程排序,然后找到 I/O 较大的那些进程。
iotop
Total DISK READ : 0.00 B/s | Total DISK WRITE : 35.27 K/s
Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 368.40 K/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
16811 be/2 root 0.00 B/s 3.92 K/s 0.00 % 0.00 % AliYunDun
从这个输出,可以看到,前两行分别表示,进程的磁盘读写大小总数和磁盘真实的读写 大小总数。因为缓存、缓冲区、I/O 合并等因素的影响,它们可能并不相等。
剩下的部分,则是从各个角度来分别表示进程的 I/O 情况,包括线程 ID、I/O 优先级、每 秒读磁盘的大小、每秒写磁盘的大小、换入和等待 I/O 的时钟百分比等。
lsof -p 23664
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
imsocket 23664 root cwd DIR 253,1 56 302019283 /data/imsocket
imsocket 23664 root rtd DIR 253,1 272 128 /
imsocket 23664 root txt REG 253,1 13773370 302024957 /data/imsocket/imsocket
imsocket 23664 root 0r FIFO 0,13 0t0 61209341 pipe
imsocket 23664 root 1w FIFO 0,13 0t0 61209342 pipe
imsocket 23664 root 2w FIFO 0,13 0t0 61209343 pipe
imsocket 23664 root 4u a_inode 0,14 0 11876 [eventpoll]
imsocket 23664 root 5r FIFO 0,13 0t0 61210406 pipe
imsocket 23664 root 6w FIFO 0,13 0t0 61210406 pipe
imsocket 23664 root 7u sock 0,9 0t0 61210408 protocol: TCP
imsocket 23664 root 9u IPv4 61211103 0t0 TCP nsqHost:43566->nsqHost:PowerAlert-nsa (ESTABLISHED)
imsocket 23664 root 10u IPv6 61212017 0t0 TCP *:9501 (LISTEN)
imsocket 23664 root 11u IPv4 61209344 0t0 TCP nsqHost:43568->nsqHost:PowerAlert-nsa (ESTABLISHED)
imsocket 23664 root 12u IPv4 61212019 0t0 TCP nsqHost:43570->nsqHost:PowerAlert-nsa (ESTABLISHED)
imsocket 23664 root 13u IPv4 61212020 0t0 TCP nsqHost:43572->nsqHost:PowerAlert-nsa (ESTABLISHED)
imsocket 23664 root 14u IPv4 61209347 0t0 TCP nsqHost:43574->nsqHost:PowerAlert-nsa (ESTABLISHED)
COMMAND:进程的名称!
FD 列中的文件描述符意义:
Type 列中的文件描述符意义:
它是 bcc 软件包的一部分,基于 Linux 内核的 eBPF(extended Berkeley Packet Filters)机制,主要跟踪内核中文件的读写情况,并 输出线程 ID(TID)、读写大小、读写类型以及文件名称。
# -C 选项表示输出新内容时不清空屏幕
filetop -C
TID COMM READS WRITES R_Kb W_Kb T FILE
27168 supervisord 0 1 0 0 R supervisord.log-20210728
156999 php 8 0 32 0 R openssl.cnf
156999 php 4 0 32 0 R SymfonyStyle.php
31177 AliYunDun 4 0 31 0 R stat
156999 php 3 0 24 0 R .env
156999 php 4 0 16 0 R hosts
156999 php 4 0 16 0 R opensslcnf.txt
我们会看到,filetop 输出了 8 列内容,分别是线程 ID、线程命令行、读写次数、读写的大 小(单位 KB)、文件类型以及读写的文件名称
多观察一会儿,就会发现,每隔一段时间,线程号为 156999 的 php 应用就会先写入的 openssl.cnf 文件,再大量地读。
运行下面的ps命令查看一下:
ps -efT |grep 156999
www 156999 156999 27168 0 17:37 ? 00:00:00 /usr/bin/php /data/api/artisan user-cache
我们看到,这个线程正是案例应用 156999 的线程。终于可以先松一口气,不过还没完, filetop 只给出了文件名称,却没有文件路径,还得继续找啊。
在使用opensnoop工具 。它同属于 bcc 软件包,可以动态跟踪内核中的 open 系统调用。这样,我们就可以找出这些文件的路径。
opensnoop
fio(Flexible I/O Tester)正是最常用的文件系统和磁盘 I/O 性能基准测试工具。它提供了大量的可定制化选项,可以用来测试,裸盘或者文件系统在各种场景下的 I/O 性能,包 括了不同块大小、不同 I/O 引擎以及是否使用缓存等场景。
安装
yum install -y fio
安装完成后,就可以执行 man fio 查询它的使用方法。
fio 的选项非常多, 我们通过几个常见场景的测试方法,介绍一些最常用的选项。这些常 见场景包括随机读、随机写、顺序读以及顺序写等,你可以执行下面这些命令来测试:
# 随机读
fio -name=randread -direct=1 -iodepth=64 -rw=randread -ioengine=libaio -bs=4k -size=1G -
# 随机写
fio -name=randwrite -direct=1 -iodepth=64 -rw=randwrite -ioengine=libaio -bs=4k -size=1G
# 顺序读
fio -name=read -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=4k -size=1G -numjobs=10
# 顺序写
fio -name=write -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=4k -size=1G -numjob
在这其中,有几个参数需要我们重点关注一下。
Linux 内核自带的高性能网络测试工具 pktgen。 pktgen 支持丰富的自定义选项,方便你根据实际需要构造所需网络包,从而更准确地测 试出目标服务器的性能。
不过,在 Linux 系统中,并不能直接找到 pktgen 命令。因为 pktgen 作为一个内核线程来运行,需要加载 pktgen 内核模块后,再通过 /proc 文件系统来交互。下面就是 pktgen 启动的两个内核线程和 /proc 文件系统的交互文件:
modprobe pktgen
ps -ef | grep pktgen| g rep-v grep 3
root 26384 2 0 06:17 ? 00:00:00 [kpktgend_0]
root 26385 2 0 06:17 ? 00:00:00 [kpktgend_1]
ls /proc/net/pktgen/
kpktgend_0 kpktgend_1 pgctrl
pktgen 在每个 CPU 上启动一个内核线程,并可以通过 /proc/net/pktgen 下面的同名文件,跟这些线程交互;而 pgctrl 则主要用来控制这次测试的开启和停止。
如果 modprobe 命令执行失败,说明你的内核没有配置
CONFIG_NET_PKTGEN 选项。这就需要你配置 pktgen 内核模块(即
CONFIG_NET_PKTGEN=m)后,重新编译内核,才可以使用。
在使用 pktgen 测试网络性能时,需要先给每个内核线程 kpktgend_X 以及测试网卡,配 置 pktgen 选项,然后再通过 pgctrl 启动测试。
说到 TCP 和 UDP 的测试,已经很熟悉了,甚至可能一下子就能想到相应的测试工具,比如 iperf 或者 netperf。
iperf 和 netperf 都是最常用的网络性能测试工具,测试 TCP 和 UDP 的吞吐量。它们都以客户端和服务器通信的方式,测试一段时间内的平均吞吐量。
接下来,我们就以 iperf 为例,看一下 TCP 性能的测试方法。目前,iperf 的最新版本为 iperf3,你可以运行下面的命令来安装:
yum install iperf3
然后,在目标机器上启动 iperf 服务端:
# -s 表示启动服务端,-i 表示汇报间隔,-p 表示监听端口
iperf3 -s -i 1 -p 10000
接着,在另一台机器上运行 iperf 客户端,运行测试:
# -c 表示启动客户端,192.168.0.30 为目标服务器的 IP 2 # -b 表示目标带宽 (单位是 bits/s)
# -t 表示测试时间
# -P 表示并发数,-p 表示目标服务器监听端口
iperf3 -c 172.31.36.80 -b 10G -t 15 -P 2 -p 10000
稍等一会儿(15 秒)测试结束后,回到目标服务器,查看 iperf 的报告:
[ ID] Interval Transfer Bitrate
[ 5] 0.00-15.04 sec 1.51 GBytes 860 Mbits/sec receiver
[ 8] 0.00-15.04 sec 1.24 GBytes 709 Mbits/sec receiver
[SUM] 0.00-15.04 sec 2.75 GBytes 1.57 Gbits/sec receiver
最后的 SUM 行就是测试的汇总结果,包括测试时间、数据传输量以及带宽等。按照发送和接收,这一部分又分为了 sender 和 receiver 两行。
从测试结果你可以看到,这台机器 TCP 接收的带宽(吞吐量)为 1.57 Gb/s, 跟目标的 10Gb/s 相比,还是有些差距的。
从传输层再往上,到了应用层。有的应用程序,会直接基于 TCP 或 UDP 构建服务。当 然,也有大量的应用,基于应用层的协议来构建服务,HTTP 就是最常用的一个应用层协 议。比如,常用的 Apache、Nginx 等各种 Web 服务,都是基于 HTTP。
要测试 HTTP 的性能,也有大量的工具可以使用,比如 ab、webbench 等,都是常用的 HTTP 压力测试工具。其中,ab 是 Apache 自带的 HTTP 压测工具,主要测试 HTTP 服 务的每秒请求数、请求延迟、吞吐量以及请求延迟的分布情况等。
运行下面的命令,你就可以安装 ab 工具:
yum install -y httpd-tools
运行 ab 命令,测试 Nginx 的性能:
# -c 表示并发请求数为 1000,-n 表示总的请求数为 10000
ab -c 1000 -n 10000 http://172.31.36.80/
....
Server Software: nginx
Server Hostname: 172.31.36.80
Server Port: 80
Document Path: /
Document Length: 3196 bytes
Concurrency Level: 1000
Time taken for tests: 0.462 seconds
Complete requests: 10000
Failed requests: 4
(Connect: 0, Receive: 0, Length: 0, Exceptions: 4)
Total transferred: 34460000 bytes
HTML transferred: 31960000 bytes
Requests per second: 21634.86 [#/sec] (mean)
Time per request: 46.222 [ms] (mean)
Time per request: 0.046 [ms] (mean, across all concurrent requests)
Transfer rate: 72806.37 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 12 1.7 12 18
Processing: 5 16 8.5 15 233
Waiting: 0 13 8.4 11 230
Total: 14 28 8.6 27 247
Percentage of the requests served within a certain time (ms)
50% 27
66% 29
75% 31
80% 31
90% 34
95% 36
98% 40
99% 41
100% 247 (longest request)
可以看到,ab 的测试结果分为三个部分,分别是请求汇总、连接时间汇总还有请求延迟汇总。以上面的结果为例,我们具体来看。
在请求汇总部分,可以看到:
连接时间汇总部分,则是分别展示了建立连接、请求、等待以及汇总等的各类时间,包括最小、最大、平均以及中值处理时间。
最后的请求延迟汇总部分,则给出了不同时间段内处理请求的百分比,比如, 90% 的请 求,都可以在 34ms 内完成。
当使用 iperf 或者 ab 等测试工具,得到 TCP、HTTP 等的性能数据后,这些数据是否就能表示应用程序的实际性能呢?我想,那肯定不是的。
比如,应用程序基于 HTTP 协议,为最终用户提供一个 Web 服务。这时,使用 ab 工具,可以得到某个页面的访问性能,但这个结果跟用户的实际请求,很可能不一致。因 为用户请求往往会附带着各种各种的负载(payload),而这些负载会影响 Web 应用程序内部的处理逻辑,从而影响最终性能。
那么,为了得到应用程序的实际性能,就要求性能工具本身可以模拟用户的请求负载,而 iperf、ab 这类工具就无能为力了。但是,我们还可以用 wrk、TCPCopy、Jmeter 或者 LoadRunner 等实现这个目标。
以 wrk 为例,它是一个 HTTP 性能测试工具,内置了 LuaJIT,方便你根据实际需求,生成所需的请求负载,或者自定义响应的处理方法。
wrk 工具本身不提供 yum 或 apt 的安装方法,需要通过源码编译来安装。
git clone https://github.com/wg/wrk.git
cd wrk
make
cp wrk /usr/local/bin/
wrk 的命令行参数比较简单。比如,我们可以用 wrk ,来重新测一下前面已经启动的 Nginx 的性能。
# -c 表示并发连接数 1000,-t 表示线程数为 2
wrk -c 1000 -t 2 http://api.tickeup.com/oss/getstsinfo/
Running 10s test @ http://api.tickeup.com/oss/getstsinfo/
2 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 286.14ms 207.38ms 1.81s 65.46%
Req/Sec 1.49k 1.16k 6.24k 77.60%
25253 requests in 10.03s, 7.60MB read
Socket errors: connect 0, read 0, write 0, timeout 315
Non-2xx or 3xx responses: 24950
Requests/sec: 2517.19
Transfer/sec: 775.54KB
这里使用 2 个线程、并发 1000 连接,测试了应用程序的性能。你可以看到,每秒请求数为 2517.19,吞吐量为 775.54KB,平均延迟为 286.14ms。
time 命令可以用来运行命令并报告CPU用量。它可能在操作系统的/usr/bin目录下,或者在shell里内建。
[root@node]# time
real 0m0.000s
user 0m0.000s
sys 0m0.000s