Linux服务器性能监控
概述
一个基于 Linux 操作系统的服务器运行的同时,也会表征出各种各样参数信息。通常来说运维人员、系统管理员会对这些数据会极为敏感,但是这些参数对于开发者来说也十分重要,尤其当你的程序非正常工作的时候,这些蛛丝马迹往往会帮助快速定位跟踪问题。
这里只是一些简单的工具查看系统的相关参数,当然很多工具也是通过分析加工 /proc、/sys 下的数据来工作的,而那些更加细致、专业的性能监测和调优,可能还需要更加专业的工具(perf、systemtap 等)和技术才能完成哦。毕竟来说,系统性能监控本身就是个大学问。
Linux 内核的各个子系统出发,汇总了对各个子系统进行性能分析时,你可以选择的工具。不过,虽然这个图是性能分析最好的参考资料之一,它其实还不够具体。比如,当你需要查看某个性能指标时,这张图里对应的子系统部分,可能有多个性能工具可供选择。但实际上,并非所有这些工具都适用,具体要用哪个,还需要你去查找每个工具的手册,对比分析做出选择。
形成认识框架
认识框架(也就是知识大纲)非常重要,宏观上有了理解之后:1)才能有的放矢的深入细节,并能将繁杂多样的细节串联起来;2)在遇到问题的时候,才有能够正确的思考,有头绪、有方法、有步骤的调查问题、解决问题。
下面这张图是最宏观的图片,从上往下是“应用->库->系统调用->内核->设备”,如果发现一个应用的性能特别不理想,可以按照这个顺序查找问题所在,即先查应用、再查依赖库、然后查系统、最后查硬件。
排查顺序
整体情况
top/htop/atop
命令查看进程/线程、CPU、内存使用情况,CPU使用情况;dstat 2
查看CPU、磁盘IO、网络IO、换页、中断、切换,系统I/O状态;vmstat 2
查看内存使用情况,内存状态;iostat -d -x 2
查看所有磁盘的IO情况,系统I/O状态;iotop
查看IO靠前的进程,系统的I/O状态;perf top
查看占用CPU最多的函数,CPU使用情况;perf record -ag -- sleep 15;perf report
查看CPU事件占比,调用栈,CPU使用情况;sar -n DEV 2
查看网卡的吞吐,网卡状态;/usr/share/bcc/tools/filetop -C
查看每个文件的读写情况,系统的I/O状态;/usr/share/bcc/tools/opensnoop
显示正在被打开的文件,系统的I/O状态;mpstat -P ALL 1
单核CPU是否被打爆;ps aux --sort=-%cpu
按CPU使用率排序,找出CPU消耗最多进程;ps -eo pid,comm,rss | awk '{m=$3/1e6;s["*"]+=m;s[$2]+=m} END{for (n in s) printf"%10.3f GB %s\n",s[n],n}' | sort -nr | head -20
统计前20内存占用;
awk 'NF>3{s["*"]+=s[$1]=$3*$4/1e6} END{for (n in s) printf"%10.1f MB %s\n",s[n],n}' /proc/slabinfo | sort -nr | head -20
统计内核前20slab的占用;
进程分析,进程占用的资源
pidstat 2 -p 进程号
查看可疑进程CPU使用率变化情况;pidstat -w -p 进程号 2
查看可疑进程的上下文切换情况;pidstat -d -p 进程号 2
查看可疑进程的IO情况;lsof -p 进程号
查看进程打开的文件;strace -f -T -tt -p 进程号
显示进程发起的系统调用;
协议栈分析,连接/协议栈状态:
ethtool -S
查看网卡硬件情况;cat /proc/net/softnet_stat/ifconfig eth1
查看网卡驱动情况;netstat -nat|awk '{print awk $NF}'|sort|uniq -c|sort -n查看连接状态分布;
ss -ntp
或者netstat -ntp
查看连接队列;netstat -s
查看协议栈情况;
方法论
RED方法:监控服务的请求数(Rate)、错误数(Errors)、响应时间(Duration)。Weave Cloud在监控微服务性能时提出的思路。
USE方法:监控系统资源的使用率(Utilization)、饱和度(Saturation)、错误数(Errors)。
CPU分析思路
从 CPU 的角度来说,主要的性能指标就是 CPU 的使用率、上下文切换以及 CPU Cache 的命中率等。下面这张图就列出了常见的 CPU 性能指标。
CPU使用情况
CPU使用分析主要就是分析CPU的使用率,看看那些进程占用的CPU资源比较多。
用户态与内核态的详细说明
用户态和内核态其实是CPU的工作模式,一些特殊的指令可以让CPU在用户态和内核态的切换。 CPU在内核态时,操作的是内核中的数据,用户态时操作的是用户态数据。
用户态进程是通过发起系统调用,进入到内核态的。
系统调用可以理解为内核提供的功能接口,用户态程序发起系统调用的时候,CPU转为内核态,完成了相关操作后,再切换回用户态。
top/htop/atop查看CPU使用情况
top命令不多说了,需要注意的是在top中键入H
后,进入线程模式。
htop和atop是两个功能更丰富的类top工具:
1 | yum install -y htop atop |
pidstat查看进程的CPU使用率
pidstat
命令可以显示每个进程的在不同CPU状态中耗费的时间的百分比(1,每秒显示一次;-p,指定进程,如果不指定,显示所有进程):
1 2 3 4 5 6 7 | $ pidstat 1 -p 27936 Linux 3.10.0-693.11.6.el7.x86_64 (10.10.64.58) 12/04/2018 _x86_64_ (4 CPU) 05:00:59 PM UID PID %usr %system %guest %CPU CPU Command 05:01:00 PM 99 27936 0.00 0.00 0.00 0.00 0 openresty 05:01:01 PM 99 27936 0.00 0.00 0.00 0.00 0 openresty 05:01:02 PM 99 27936 0.00 0.00 0.00 0.00 0 openresty |
perf top查看CPU占用高的函数
perf top
显示占用CPU时间最多的函数或者指令:
1 2 3 4 5 6 7 8 9 10 11 | $ perf top Samples: 3K of event 'cpu-clock', Event count (approx.): 903937500 Overhead Shared Object Symbol 8.69% perf [.] symbols__insert 5.33% perf [.] rb_next 3.41% [kernel] [k] _raw_spin_unlock_irqrestore 3.12% libc-2.17.so [.] __memcpy_ssse3_back 2.40% [kernel] [k] finish_task_switch 2.40% libc-2.17.so [.] __strchr_sse42 2.08% libelf-0.168.so [.] gelf_getsym ...省略后续内容... |
perf report查看cpu事件占比
用perf record
将采样数据保存,然后用perf record
查看,或者直接用下面的命令一次完成,-a
查看所有cpu:
1 | perf record -ag -- sleep 15;perf report |
perf report中显示,stress进程的cpu事件占比是77%,它大量调用了随机数生成函数random():
vmstat查看上下文切换
vmstat
命令显示系统整体状态,输出如下:
1 2 3 4 | $ vmstat 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 5980 126076 648 6997448 0 0 6 27 13 1 1 1 97 0 0 |
可以在后面加上一个数字,每隔指定时间输出一次,例如vmstat 5
,如果感觉数据排列太密集,可以加上参数-w
,用宽格式显示。
vmstat命令的输出包含procs
、memory
、 swap
、io
、system
和cpu
六块内容。
每列数据的含义如下,可以在man vmstat
中找到:
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 | Procs r: The number of runnable processes (running or waiting for run time). b: The number of processes in uninterruptible sleep. Memory swpd: the amount of virtual memory used. free: the amount of idle memory. buff: the amount of memory used as buffers. cache: the amount of memory used as cache. inact: the amount of inactive memory. (-a option) active: the amount of active memory. (-a option) Swap si: Amount of memory swapped in from disk (/s). so: Amount of memory swapped to disk (/s). IO bi: Blocks received from a block device (blocks/s). bo: Blocks sent to a block device (blocks/s). System in: The number of interrupts per second, including the clock. cs: The number of context switches per second. CPU These are percentages of total CPU time. us: Time spent running non-kernel code. (user time, including nice time) sy: Time spent running kernel code. (system time) id: Time spent idle. Prior to Linux 2.5.41, this includes IO-wait time. wa: Time spent waiting for IO. Prior to Linux 2.5.41, included in idle. st: Time stolen from a virtual machine. Prior to Linux 2.6.11, unknown. |
其中cs
是一秒内发生的上下文切换次数。
pidstat查看特定进程的切换情况
pidstat -w
可以显示每个进程的上下文切换情况:
1 2 3 4 5 6 7 8 | $ pidstat -w Linux 3.10.0-693.11.6.el7.x86_64 (10.10.64.58) 12/04/2018 _x86_64_ (4 CPU) 04:04:15 PM UID PID cswch/s nvcswch/s Command 04:04:15 PM 0 1 1.75 0.00 systemd 04:04:15 PM 0 2 0.01 0.00 kthreadd 04:04:15 PM 0 3 2.54 0.00 ksoftirqd/0 ...省略后续内容... |
(可以在后面上一个数字,每隔指定时间输出一次,例如pidstat -w 5
)
特别注意:pidstats -w显示的是进程的状态,如果要将线程一并显示出来,需要再加一个-t参数:
1 2 3 4 5 6 7 8 9 10 | $ pidstat -wt Average: UID TGID TID cswch/s nvcswch/s Command Average: 0 3 - 3.92 0.00 ksoftirqd/0 Average: 0 - 3 3.92 0.00 |__ksoftirqd/0 Average: 0 9 - 45.59 0.00 rcu_sched Average: 0 - 9 45.59 0.00 |__rcu_sched Average: 0 13 - 1.96 0.00 ksoftirqd/1 Average: 0 - 13 1.96 0.00 |__ksoftirqd/1 Average: 0 17 - 0.49 0.00 migration/2 ...省略后续内容... |
-w
参数的作用是显示进程切换状态,每一列的含义如下(可以在man pidstat
中找到):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | -w Report task switching activity (kernels 2.6.23 and later only). The following values may be displayed: UID The real user identification number of the task being monitored. USER The name of the real user owning the task being monitored. PID The identification number of the task being monitored. cswch/s Total number of voluntary context switches the task made per second. A voluntary context switch occurs when a task blocks because it requires a resource that is unavailable. nvcswch/s Total number of non voluntary context switches the task made per second. A involuntary context switch takes place when a task executes for the duration of its time slice and then is forced to relinquish the processor. Command The command name of the task. |
需要注意自愿切换(cswch/s,voluntary context switches)和非自愿切换(nvcswch/s,non voluntary context switches)的区别。前者是因为需要的资源没有准备好,主动让出CPU发生的切换,后者是进程分配的时间片已经用完,被调度器强制切换。
另外pidstat还有一个-u
参数,可以一并输出进程和线程(加-t)的CPU使用情况:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [root@10.10.64.58 ~]# pidstat -wt -u Linux 3.10.0-693.11.6.el7.x86_64 (10.10.64.58) 12/04/2018 _x86_64_ (4 CPU) 04:21:56 PM UID TGID TID %usr %system %guest %CPU CPU Command 04:21:56 PM 0 1 - 0.02 0.01 0.00 0.03 0 systemd 04:21:56 PM 0 - 1 0.02 0.01 0.00 0.03 0 |__systemd 04:21:56 PM 0 2 - 0.00 0.00 0.00 0.00 0 kthreadd 04:21:56 PM 0 - 2 0.00 0.00 0.00 0.00 0 |__kthreadd ...省略后续内容... 04:21:56 PM UID TGID TID cswch/s nvcswch/s Command 04:21:56 PM 0 1 - 1.75 0.00 systemd 04:21:56 PM 0 - 1 1.75 0.00 |__systemd 04:21:56 PM 0 2 - 0.01 0.00 kthreadd 04:21:56 PM 0 - 2 0.01 0.00 |__kthreadd 04:21:56 PM 0 3 - 2.53 0.00 ksoftirqd/0 ...省略后续内容... |
/proc/interrupts记录的中断状态
watch -d cat /proc/interrupts
用可以显示中断的变化情况。
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 | Every 2.0s: cat /proc/interrupts Tue Dec 4 16:29:25 2018 CPU0 CPU1 CPU2 CPU3 0: 153 0 0 0 IO-APIC-edge timer 1: 10 0 0 0 IO-APIC-edge i8042 6: 3 0 0 0 IO-APIC-edge floppy 8: 0 0 0 0 IO-APIC-edge rtc0 9: 0 0 0 0 IO-APIC-fasteoi acpi 10: 0 0 0 0 IO-APIC-fasteoi virtio0 11: 31 0 3 0 IO-APIC-fasteoi uhci_hcd:usb1 12: 15 0 0 0 IO-APIC-edge i8042 14: 0 0 0 0 IO-APIC-edge ata_piix 15: 0 0 0 0 IO-APIC-edge ata_piix 24: 0 0 0 0 PCI-MSI-edge virtio3-config 25: 6234 0 120283 272843 PCI-MSI-edge virtio3-req.0 26: 0 0 0 0 PCI-MSI-edge virtio1-config 27: 99 176029503 172147021 0 PCI-MSI-edge virtio1-input.0 28: 24 2721 497 4165 PCI-MSI-edge virtio1-output.0 29: 0 0 0 0 PCI-MSI-edge virtio2-config 30: 19 0 0 0 PCI-MSI-edge virtio2-virtqueues 31: 0 0 0 0 PCI-MSI-edge virtio4-config 32: 131111 0 0 0 PCI-MSI-edge virtio4-req.0 NMI: 0 0 0 0 Non-maskable interrupts LOC: 64284244 70653905 70450086 65741168 Local timer interrupts SPU: 0 0 0 0 Spurious interrupts PMI: 0 0 0 0 Performance monitoring interrupts IWI: 1242971 1424513 1360783 1296367 IRQ work interrupts RTR: 0 0 0 0 APIC ICR read retries RES: 33708963 29562936 30300354 32946303 Rescheduling interrupts CAL: 131150935 64213698 67023823 133615842 Function call interrupts TLB: 519133 541110 531432 522850 TLB shootdowns TRM: 0 0 0 0 Thermal event interrupts THR: 0 0 0 0 Threshold APIC interrupts DFR: 0 0 0 0 Deferred Error APIC interrupts MCE: 0 0 0 0 Machine check exceptions MCP: 2001 2001 2001 2001 Machine check polls ERR: 0 MIS: 0 PIN: 0 0 0 0 Posted-interrupt notification event PIW: 0 0 0 0 Posted-interrupt wakeup event |
Rescheduling interrupts
是重调度中断,用来唤醒空闲的CPU执行新的任务。
内存分析思路
从内存的角度来说,主要的性能指标,就是系统内存的分配和使用、进程内存的分配和使用以及 SWAP 的用量。下面这张图列出了常见的内存性能指标。
IO分析思路
从文件系统和磁盘 I/O 的角度来说,主要性能指标,就是文件系统的使用、缓存和缓冲区的使用,以及磁盘 I/O 的使用率、吞吐量和延迟等。下面这张图列出了常见的 I/O 性能指标。
网络分析思路
从网络的角度来说,主要性能指标就是吞吐量、响应时间、连接数、丢包数等。根据 TCP/IP 网络协议栈的原理,我们可以把这些性能指标,进一步细化为每层协议的具体指标。这里我同样用一张图,分别从链路层、网络层、传输层和应用层,列出了各层的主要指标。
文件系统分析思路
IO指标与工具映射表:
基准测试工具
除了性能分析外,很多时候,我们还需要对系统性能进行基准测试。比如,
- 在文件系统和磁盘 I/O 模块中,我们使用 fio 工具,测试了磁盘 I/O 的性能。
- 在网络模块中,我们使用 iperf、pktgen 等,测试了网络的性能。
- 而在很多基于 Nginx 的案例中,我们则使用 ab、wrk 等,测试 Nginx 应用的性能。
CPU和内存类
top
参考:
https://www.xmmup.com/linuxxitongzhongdepingjunfuzai.html
https://www.xmmup.com/linuxchakanzuixiaohaoneicundejincheng.html
第一行后面的三个值是系统在之前 1、5、15 的平均负载,也可以看出系统负载是上升、平稳、下降的趋势,当这个值超过 CPU 可执行单元的数目,则表示 CPU 的性能已经饱和成为瓶颈了。
第二行统计了系统的任务状态信息。running 很自然不必多说,包括正在 CPU 上运行的和将要被调度运行的;sleeping 通常是等待事件(比如 IO 操作)完成的任务,细分可以包括 interruptible 和 uninterruptible 的类型;stopped 是一些被暂停的任务,通常发送 SIGSTOP 或者对一个前台任务操作 Ctrl-Z 可以将其暂停;zombie 僵尸任务,虽然进程终止资源会被自动回收,但是含有退出任务的 task descriptor 需要父进程访问后才能释放,这种进程显示为 defunct 状态,无论是因为父进程提前退出还是未 wait 调用,出现这种进程都应该格外注意程序是否设计有误。
第三行 CPU 占用率根据类型有以下几种情况:
(us) user:CPU 在低 nice 值(高优先级)用户态所占用的时间(nice<=0)。正常情况下只要服务器不是很闲,那么大部分的 CPU 时间应该都在此执行这类程序
(sy) system:CPU 处于内核态所占用的时间,操作系统通过系统调用(system call)从用户态陷入内核态,以执行特定的服务;通常情况下该值会比较小,但是当服务器执行的 IO 比较密集的时候,该值会比较大
(ni) nice:CPU 在高 nice 值(低优先级)用户态以低优先级运行占用的时间(nice>0)。默认新启动的进程 nice=0,是不会计入这里的,除非手动通过 renice 或者 setpriority() 的方式修改程序的nice值
(id) idle:CPU 在空闲状态(执行 kernel idle handler )所占用的时间
(wa) iowait:等待 IO 完成做占用的时间
(hi) irq:系统处理硬件中断所消耗的时间
(si) softirq:系统处理软中断所消耗的时间,记住软中断分为 softirqs、tasklets (其实是前者的特例)、work queues,不知道这里是统计的是哪些的时间,毕竟 work queues 的执行已经不是中断上下文了
(st) steal:在虚拟机情况下才有意义,因为虚拟机下 CPU 也是共享物理 CPU 的,所以这段时间表明虚拟机等待 hypervisor 调度 CPU 的时间,也意味着这段时间 hypervisor 将 CPU 调度给别的 CPU 执行,这个时段的 CPU 资源被“stolen”了。这个值在我 KVM 的 VPS 机器上是不为 0 的,但也只有 0.1 这个数量级,是不是可以用来判断 VPS 超售的情况?
CPU 占用率高很多情况下意味着一些东西,这也给服务器 CPU 使用率过高情况下指明了相应地排查思路:
当 user 占用率过高的时候,通常是某些个别的进程占用了大量的 CPU,这时候很容易通过 top 找到该程序;此时如果怀疑程序异常,可以通过 perf 等思路找出热点调用函数来进一步排查;
当 system 占用率过高的时候,如果 IO 操作(包括终端 IO)比较多,可能会造成这部分的 CPU 占用率高,比如在 file server、database server 等类型的服务器上,否则(比如>20%)很可能有些部分的内核、驱动模块有问题;
当 nice 占用率过高的时候,通常是有意行为,当进程的发起者知道某些进程占用较高的 CPU,会设置其 nice 值确保不会淹没其他进程对 CPU 的使用请求;
当 iowait 占用率过高的时候,通常意味着某些程序的 IO 操作效率很低,或者 IO 对应设备的性能很低以至于读写操作需要很长的时间来完成;
当 irq/softirq 占用率过高的时候,很可能某些外设出现问题,导致产生大量的irq请求,这时候通过检查 /proc/interrupts 文件来深究问题所在;
本人提供Oracle、MySQL、PG等数据库的培训和考证业务,私聊QQ646634621或微信db_bao,谢谢!当 steal 占用率过高的时候,黑心厂商虚拟机超售了吧!
第四行和第五行是物理内存和虚拟内存(交换分区)的信息:
total = free + used + buff/cache,现在buffers和cached Mem信息总和到一起了,但是buffers和cached Mem 的关系很多地方都没说清楚。其实通过对比数据,这两个值就是 /proc/meminfo 中的 Buffers 和 Cached 字段:Buffers 是针对 raw disk 的块缓存,主要是以 raw block 的方式缓存文件系统的元数据(比如超级块信息等),这个值一般比较小(20M左右);而 Cached 是针对于某些具体的文件进行读缓存,以增加文件的访问效率而使用的,可以说是用于文件系统中文件缓存使用。
而 avail Mem 是一个新的参数值,用于指示在不进行交换的情况下,可以给新开启的程序多少内存空间,大致和 free + buff/cached 相当,而这也印证了上面的说法,free + buffers + cached Mem才是真正可用的物理内存。并且,使用交换分区不见得是坏事情,所以交换分区使用率不是什么严重的参数,但是频繁的 swap in/out 就不是好事情了,这种情况需要注意,通常表示物理内存紧缺的情况。
最后是每个程序的资源占用列表,其中 CPU 的使用率是所有 CPU core 占用率的总和。通常执行 top 的时候,本身该程序会大量的读取 /proc 操作,所以基本该 top 程序本身也会是名列前茅的。
top 虽然非常强大,但是通常用于控制台实时监测系统信息,不适合长时间(几天、几个月)监测系统的负载信息,同时对于短命的进程也会遗漏无法给出统计信息。
vmstat
vmstat 是除 top 之外另一个常用的系统检测工具:
每个输出列的含义请参考:https://www.xmmup.com/linux-vmstatmingling.html
pidstat
如果想对某个进程进行全面具体的追踪,没有什么比 pidstat 更合适的了——栈空间、缺页情况、主被动切换等信息尽收眼底。这个命令最有用的参数是-t,可以将进程中各个线程的详细信息罗列出来。
-r:显示缺页错误和内存使用状况,缺页错误是程序需要访问映射在虚拟内存空间中但是还尚未被加载到物理内存中的一个分页,缺页错误两个主要类型是
minflt/s 指的 minor faults,当需要访问的物理页面因为某些原因(比如共享页面、缓存机制等)已经存在于物理内存中了,只是在当前进程的页表中没有引用,MMU 只需要设置对应的 entry 就可以了,这个代价是相当小的
majflt/s 指的 major faults,MMU 需要在当前可用物理内存中申请一块空闲的物理页面(如果没有可用的空闲页面,则需要将别的物理页面切换到交换空间去以释放得到空闲物理页面),然后从外部加载数据到该物理页面中,并设置好对应的 entry,这个代价是相当高的,和前者有几个数据级的差异
-s:栈使用状况,包括 StkSize 为线程保留的栈空间,以及 StkRef 实际使用的栈空间。使用ulimit -s发现CentOS 6.x上面默认栈空间是10240K,而 CentOS 7.x、Ubuntu系列默认栈空间大小为8196K
-u:CPU使用率情况,参数同前面类似
-w:线程上下文切换的数目,还细分为cswch/s因为等待资源等因素导致的主动切换,以及nvcswch/s线程CPU时间导致的被动切换的统计
如果每次都先ps得到程序的pid后再操作pidstat会显得很麻烦,所以这个杀手锏的-C可以指定某个字符串,然后Command中如果包含这个字符串,那么该程序的信息就会被打印统计出来,-l可以显示完整的程序名和参数
1 | pidstat -w -t -C “ailaw” -l |
这么看来,如果查看单个尤其是多线程的任务时候,pidstat比常用的ps更好使!
其他
当需要单独监测单个 CPU 情况的时候,除了 htop 还可以使用 mpstat,查看在 SMP 处理器上各个 Core 的工作量是否负载均衡,是否有某些热点线程占用 Core。
1 | mpstat -P ALL 1 |
如果想直接监测某个进程占用的资源,既可以使用top -u taozj的方式过滤掉其他用户无关进程,也可以采用下面的方式进行选择,ps命令可以自定义需要打印的条目信息:
while :; do ps -eo user,pid,ni,pri,pcpu,psr,comm | grep ‘ailawd’; sleep 1; done
如想理清继承关系,下面一个常用的参数可以用于显示进程树结构,显示效果比pstree详细美观的多
1 | ps axjf |
磁盘IO类
iotop 可以直观的显示各个进程、线程的磁盘读取实时速率;lsof 不仅可以显示普通文件的打开信息(使用者),还可以操作 /dev/sda1 这类设备文件的打开信息,那么比如当分区无法 umount 的时候,就可以通过 lsof 找出磁盘该分区的使用状态了,而且添加 +fg 参数还可以额外显示文件打开 flag 标记。
iostat
参考:https://www.xmmup.com/linux-iostatmingling.html
1 | iostat -xz 1 |
其实无论使用 iostat -xz 1 还是使用 sar -d 1,对于磁盘重要的参数是:
avgqu-s:发送给设备 I/O 请求的等待队列平均长度,对于单个磁盘如果值>1表明设备饱和,对于多个磁盘阵列的逻辑磁盘情况除外
await(r_await、w_await):平均每次设备 I/O 请求操作的等待时间(ms),包含请求排列在队列中和被服务的时间之和;
svctm:发送给设备 I/O 请求的平均服务时间(ms),如果 svctm 与 await 很接近,表示几乎没有 I/O 等待,磁盘性能很好,否则磁盘队列等待时间较长,磁盘响应较差;
%util:设备的使用率,表明每秒中用于 I/O 工作时间的占比,单个磁盘当 %util>60% 的时候性能就会下降(体现在 await 也会增加),当接近100%时候就设备饱和了,但对于有多个磁盘阵列的逻辑磁盘情况除外;
还有,虽然监测到的磁盘性能比较差,但是不一定会对应用程序的响应造成影响,内核通常使用 I/O asynchronously 技术,使用读写缓存技术来改善性能,不过这又跟上面的物理内存的限制相制约了。
上面的这些参数,对网络文件系统也是受用的。
iotop
参考:https://www.xmmup.com/linux-iotopminglingjieshao.html
网络类
网络性能对于服务器的重要性不言而喻,工具 iptraf 可以直观的现实网卡的收发速度信息,比较的简洁方便通过 sar -n DEV 1 也可以得到类似的吞吐量信息,而网卡都标配了最大速率信息,比如百兆网卡千兆网卡,很容易查看设备的利用率。
通常,网卡的传输速率并不是网络开发中最为关切的,而是针对特定的 UDP、TCP 连接的丢包率、重传率,以及网络延时等信息。
netstat
1 | netstat -s |
显示自从系统启动以来,各个协议的总体数据信息。虽然参数信息比较丰富有用,但是累计值,除非两次运行做差才能得出当前系统的网络状态信息,亦或者使用 watch 眼睛直观其数值变化趋势。所以netstat通常用来检测端口和连接信息的:
netstat –all(a) –numeric(n) –tcp(t) –udp(u) –timers(o) –listening(l) –program(p)
–timers可以取消域名反向查询,加快显示速度;比较常用的有
➜ ~ netstat -antp #列出所有TCP的连接
➜ ~ netstat -nltp #列出本地所有TCP侦听套接字,不要加-a参数
sar
sar 这个工具太强大了,什么 CPU、磁盘、页面交换啥都管,这里使用 -n 主要用来分析网络活动,虽然网络中它还给细分了 NFS、IP、ICMP、SOCK 等各种层次各种协议的数据信息,我们只关心 TCP 和 UDP。下面的命令除了显示常规情况下段、数据报的收发情况,还包括
TCP
1 | sar -n TCP,ETCP 1 |
active/s:本地发起的 TCP 连接,比如通过 connect(),TCP 的状态从CLOSED -> SYN-SENT
passive/s:由远程发起的 TCP 连接,比如通过 accept(),TCP 的状态从LISTEN -> SYN-RCVD
retrans/s(tcpRetransSegs):每秒钟 TCP 重传数目,通常在网络质量差,或者服务器过载后丢包的情况下,根据 TCP 的确认重传机制会发生重传操作
isegerr/s(tcpInErrs):每秒钟接收到出错的数据包(比如 checksum 失败)
UDP
➜ ~ sudo sar -n UDP 1
noport/s(udpNoPorts):每秒钟接收到的但是却没有应用程序在指定目的端口的数据报个数
idgmerr/s(udpInErrors):除了上面原因之外的本机接收到但却无法派发的数据报个数
当然,这些数据一定程度上可以说明网络可靠性,但也只有同具体的业务需求场景结合起来才具有意义。
tcpdump
tcpdump 不得不说是个好东西。大家都知道本地调试的时候喜欢使用 wireshark,但是线上服务端出现问题怎么弄呢?
附录的参考文献给出了思路:复原环境,使用 tcpdump 进行抓包,当问题复现(比如日志显示或者某个状态显现)的时候,就可以结束抓包了,而且 tcpdump 本身带有 -C/-W 参数,可以限制抓取包存储文件的大小,当达到这个这个限制的时候保存的包数据自动 rotate,所以抓包数量总体还是可控的。此后将数据包拿下线来,用 wireshark 想怎么看就怎么看,岂不乐哉!tcpdump 虽然没有 GUI 界面,但是抓包的功能丝毫不弱,可以指定网卡、主机、端口、协议等各项过滤参数,抓下来的包完整又带有时间戳,所以线上程序的数据包分析也可以这么简单。
下面就是一个小的测试,可见 Chrome 启动时候自动向 Webserver 发起建立了三条连接,由于这里限制了 dst port 参数,所以服务端的应答包被过滤掉了,拿下来用 wireshark 打开,SYNC、ACK 建立连接的过程还是很明显的!在使用 tcpdump 的时候,需要尽可能的配置抓取的过滤条件,一方面便于接下来的分析,二则 tcpdump 开启后对网卡和系统的性能会有影响,进而会影响到在线业务的性能。
线程查看
若想查看某个进程下的线程详情,可以使用如下命令:
1 2 3 4 5 | pstree -p pid ps -eLf | grep pid ps -Lf pid pstack pid top -Hp pid |