Linux问题诊断工具箱
前言
当应用层面没有足够的上下文信息做性能诊断时,利用Linux内置的工具命令协助性能诊断时必备的技能之一,本文总结一些比较常用的Linux性能诊断命令。Linux操作系统的可观测行很好,从CPU、磁盘、网卡、文件系统到内存都有对应的诊断工具。
工具安装与准备
平时使用的工具最好是优先掌握Linux系统内置的命令(无需额外安装)以及各大主流Linux发行版包管理中都可以下载到的工具。
sysstat工具集
sysstat是一个工具集合,一般通过yum或者apt-get即可直接安装
1 | # 安装 |
sysstat工具包包含的工具:
- iostat 工具提供CPU使用率及硬盘吞吐效率的数据; #比较核心的工具
- mpstat 工具提供单个处理器或多个处理器相关数据;
- pidstat: 关于运行中的进程/任务、CPU、内存等的统计信息
- sar 工具负责收集、报告并存储系统活跃的信息; #统计数据的核心工具
- sa1 工具负责收集并存储每天系统动态信息到一个二进制的文件中。它是通过计划任务工具cron来运行,是为sadc所设计的程序前端程序;
- sa2工具负责把每天的系统活跃性息写入总结性的报告中。它是为sar所设计的前端 ,要通过cron来调用
- sadc 是系统动态数据收集工具,收集的数据被写一个二进制的文件中,它被用作sar工具的后端;
- sadf 显示被sar通过多种格式收集的数据;
- nfsiostat: NFS(Network File System)的I/O统计信息。
- cifsiostat: CIFS(Common Internet File System)的统计信息
bcc-tools
bcc工具集,基于bcc配合eBPF的工具集合。注意内核版本太低不太可用,最起码4.1以上,最好内核版本4.9及以上。更多使用示例的话可以参考bcc项目代码;
由于bcc-tools本质是eBPF程序。更多eBPF tool有兴趣的话可以参考Linux Extended BPF (eBPF) Tracing Tools。 BPF实现的工具如果熟练使用,基本整个操作系统的观测程度就非常高了,下图展示了操作系统各个层面支持的BPF工具。不过我们能直接安装好的bcc-tools是这边工具的一个子集。
1 | # Ubuntu |
以下是装好有/usr/share/bcc/tools可以看到一些命令。本文篇幅有限,会挑选几个自己觉得比较重要的几个来说明下。
全局概览统计信息查看工具
top
top包含信息比较完整,可以通过-Hp查看特定进程的CPU使用情况,也可以查看实时的cpu load的实时变化情况,是最为常用的命令之一。
vmstat
适合查看整体的情况
1 | vmstat 1 |
sar
sar工具包含在sysstat工具中,是sysstat中很强大的工具。其不同的参数可以对各个组件获取统计信息,最重要的是,其能查看历史数据。下文中谈到具体组件时会演示如何使用sar。
pidstat
也是可以看cpu、内存、IO的工具命令。相比sar的优点是他可以看到进程级别的信息,在排查特定进程某个指标时会特别有用。
CPU相关诊断工具
mpstat与/proc/stat
mp是multi processor的缩写。mpstat主要获取多核CPU性能的统计信息。这些信息来自/proc/stat。常用的用法如下。
1 | # -P: {|ALL} 表示监控哪个CPU, cpu在[0,cpu个数-1]中取值 |
- %user:在internal时间段里,用户态的CPU时间(%),不包含nice值为负进程 (usr/total)*100
- %nice:在internal时间段里,nice值为负进程的CPU时间(%) (nice/total)*100
- %sys :在internal时间段里,内核时间(%) (system/total)*100
- %iowait:在internal时间段里,硬盘IO等待时间(%) (iowait/total)*100
- %irq:在internal时间段里,硬中断时间(%) (irq/total)*100
- %soft:在internal时间段里,软中断时间(%) (softirq/total)*100
- %idle:在internal时间段里,CPU除去等待磁盘IO操作外的因为任何原因而空闲的时间闲置时间(%) (idle/total)*100
/proc/interrtupts和/proc/softirqs
一般全局如果发现CPU中断有些问题,比如中断过高或者不均匀。我们还需要定位具体是哪个外部设备引发的中断。配合watch命令可以每隔一定时间刷新,观察数值变化确定是具体什么设备和操作产生了较大的中断开销。
1 | watch -n1 -d cat /proc/softirqs |
lscpu和/proc/cpuinfo
查看CPU个数和缓存大小等信息
火焰图(flamegraph)
cpu热点函数很适合通过火焰图来分析。随着eBPF特性在Linux内核的支持,现在也支持采用eBPF的方式生成火焰图了,更加高效不用生成perf.data,直接在内核内统计。
考虑到兼容性,一般用perf生成火焰图使用范围更加宽。
1 | ### Linux 内核2.6以上使用perf |
4.9以上支持BPF的Linux内核可以使用BPF的方式,性能更好
1 | ### Linux内核4.9+以上使用BPF |
一般线上排查问题只关注一个进程的时候直接用perf record也挺方便,因为本身东西也不多
cpu相关的sar命令
其实有多个cpu相关的命令,但是从实用性来说,我觉得记忆如下两个就够了。sar用来看CPU上下文切换和中断的用mpstat看更加清楚。其中saq -q用来看排队还是挺实用的
1 | # 间隔1秒3次,输出进程的cpu使用率,u代表utilization |
忘记字段含义的话直接man sar然后搜索下字段名字就可以确认
pidstat
直接使用该命令等价于使用**pidstat -u -p ALL,**配合grep可以查看各个进程的cpu使用率情况。
内存相关诊断工具
内存可以监控的包含很多种类。
内存相关的sar命令
sar命令很强,可以看各种细致的进程内存使用情况。不过一般熟悉-r和-B即可。-r看内存利用率,-B主要看内存页的统计信息,内存页的读写、缺页中断(page fault)等信息。
pidstat -r查看ram内存统计
配合grep可以只看特定进程的
pmap查看进程内存映射
可以看到进程具体内存映射情况,用于定位进程的内存瓶颈。
1 | ## 查看当前进程内存映射,占用最多的10个 |
找到异常的内存块要看内容可以配合gdb命令把内存块dump出来。步骤如下:
- 通过smaps可以输出进程使用的内存块详细信息,包括地址范围和来源:
1 | cat /proc/<pid>/smaps > smaps.txt |
- 找到包含异常内存地址的地址范围
- gdb attach
- dump指定内存地址到指定的目录下,参数的地址需要在smaps拿到地址前加上0x
1 | dump memory /tmp/0x7fb9b0000000-0x7fb9b3ffe000.dump 0x7fb9b0000000 0x7fb9b3ffe000 |
- 显示长度超过10字符的字符串
1 | strings -10 /tmp/0x7fb9b0000000-0x7fb9b3ffe000.dump |
memleak查看内存泄露
使用案例可以参考memleak_example.txt,基本用法其实还是比较简单的
1 | ./memleak -p ${PID} |
cachestat、cachetop查看page cache命中率情况
cachetop查看进程全局命中情况,排查或者优化一些读写性能的时候可以考虑追踪下page cache的情况
cachestat则看系统全局的命中率:
磁盘I/O
pidstat -d
查看进程的I/O可以用
1 | pidstat -d |
iostat
这个效果和sar -d的效果几乎一样,记住用一个就够了,我们用sar
sar
1 | # sar -d 1 |
biosnoop追踪数据块实时写入情况
bcc-tool工具之一,实时追踪块设备写入,可以用来哪些行为导致磁盘性能劣化。
1 | ./usr/share/bcc/tools/biosnoop |
biolatency块设备延迟统计直方图
1 | ./usr/share/bcc/tools/biolatency |
默认是微秒,可以-m指定看毫秒的结果
网络相关
netstat
查看connection和端口占用很常用。不过现在有ss了,推荐用ss性能更好
1 | netstat -antlp| grep ${PID} |
ss
1 | ss -antp| grep ${PID} |
sar -n DEV 查看网络I/O
dev即指的是network device。这边-n后面支持的类型有:DEV, EDEV, NFS, NFSD, SOCK, IP, EIP, ICMP, EICMP, TCP, ETCP, UDP, SOCK6, IP6, EIP6, ICMP6, EICMP6 and UDP6. 一般常用的我们记住下面两个就够用了
1 | ### 查看网络I/O |
DEV的结果
tcpretrans查看重连
1 | ./usr/share/bcc/tools/tcpretrans |
相比sar查看重传,tcpretrans能比较精确定位到产生重传的进程,定位更加直接。
ethtool查看网卡情况
1 | ## 查看网卡基本情况 |
mtr命令查看每一跳的丢包情况
默认没有需要安装下,yum install mtr
1 | mtr -r baidu.com |
traceroute查看每一跳延迟
yum install traceroute先安装下
1 | traceroute -n 180.101.50.172 |
ifconfig查看网卡流控队列、drop情况
网卡性能不足有时候也会导致网络丢包,可以看看drop情况。不过一般千兆网卡不太可能被打满
文件系统
/proc/${pid}/fd 查看进程文件句柄占用
文件句柄没有及时关闭这类问题也会发生,一般是用于没有正确关闭流导致。
1 | ls -l /proc/${pid}/fd|wc -l |
open系统调用追踪opensnoop
bcc-tool工具之一,需要先安装bcc-tool。这个用来看实时的进程fd占用和打开文件的情况很有用。
1 | ./usr/share/bcc/tools/opensnoop -p ${pid} |
ext4slower查看ext4文件系统的slow write
bcc-tool工具之一,需要先安装bcc-tool。查看ext4文件系统实时的慢写入很有用。
1 | ## 第一个数字代表阈值毫秒,查询写入延迟2毫秒以上的行为 |
cachestat查看文件系统缓存命中
1 | ./usr/share/bcc/tools/cachestat |
其他
内核日志dmesg
dmesg主要用来查看内核环形缓冲区的日志。kernel ring buffer是个固定大小的空间,在系统引导时,内核将与硬件和模块初始化相关的信息填到这个缓冲区中。常见用于排查的问题例如:
- 系统启动与硬件初始化相关问题
- 硬件的异常行为,比如网络sync flood、oom_killer执行(本质是内核关联RAM的行为)
常用命令如下
1 | # 查看系统层面warning error级别日志 |
execsnoop查看实时进程启动
排查一些不符合预期的进程拉起会比较有用。不过没有跟踪fork/clone/vfork,子进程创建不监控。
1 | ./usr/share/bcc/tools/execsnoop |
实际应用
网卡软中断不均衡导致丢包
以前在阿里工作时就遇到过双十一压测性能上不去有丢包导致的网络重传,最后发现是多队列网卡软中断不均衡导致的,后来通过irq亲缘绑定解决的。这个可以参考网卡软终端不均衡问题及解决方案。
查找网卡发送、接收队列的中断号,查看亲缘绑定。
参考资料
- [微信公众号] Linux查看硬件信息超强命令sar,以及可视化工具ksar
- 记一次堆外内存泄漏排查过程
- [微信公众号] 技术分享 | 如何使用 bcc 工具观测 MySQL 延迟
- brenadangregg个人博客
- 记一次 request_sock_tcp possible syn flooding on port 事件处理
- SYN flooding处理–内核调优
- Linux dmesg命令介绍
- [微信公众号] 那些神乎其神的eBPF bcc小工具
- 网卡软终端不均衡问题及解决方案
- 关于网卡中断不均衡问题及其解决方案 _
- 关于网卡中断不均衡问题及其解决方案 _