后台开发人员经常需要处理 Linux 系统故障,然而常常面临难以重复故障现象、难以精确找到问题根源、以及两三天都无法有效缩小问题范围的困境。本文作者收集并归纳了 Linux 后台开发中常用的诊断工具和排错方法,重点涵盖 CPU、内存、存储和通信这四个关键领域,并将这些内容整理成思维导图,旨在帮助读者更便捷地掌握和查找相关信息。赶紧点赞转发收藏一键三连起来吧!
01、分析工具
Linux 拥有多种性能检测手段,部分手段具备相似用途,能够针对同类数据执行操作;而另一些状况则必须结合多种手段联合诊断。此处呈现的图表,归纳了若干典型应用工具。
(公众号对话框回复关键词0801,获取两张高清思维导图)
02、分析方法
后台开发人员经常需要在 Linux 环境下进行故障诊断,遇到疑难杂症时,往往茫然无措,有时甚至耗费数日才能解决,因此,尽快界定问题边界并找出症结所在,避免对产品进度造成延误,是每位开发人员的共同期望。
我参考过往记录绘制了故障排查流程图,意图借此给出解题方向。当依照图示抵达末端节点时,或许无法直接找到答案,却有可能明晰了症结所在,并收集到必要资料,从而利于网络检索和向他人求教。图片所表达的含义并非按照 CPU、内存、磁盘、网络的顺序逐一检查,一旦能够清晰地识别出哪个环节存在故障,就应当直接从该故障环节开始向下游进行排查。
下面的内容是对上图进行展开。
03、CPU 使用有问题?

使用 top 等命令查看 CPU 使用率和负载是否过高。
处理器大部分时间用于核心活动吗?借助 top 指令检测核心占用率是否过高。核心是否处理大量中断请求?可借助 procinfo 工具或执行 cat /proc/interrupts 命令,用以审视中断频次、速率,并识别出引发高频中断的硬件设备。核心运行时主要消耗在哪些环节?借助 oprofile 查找耗时长内核函数,并探究其作用,明确它们归属的子系统,比如内存、网络或磁盘,分析可能被频繁调用的缘由。倘若这些函数与设备相关,需探究为何选用该设备,特别是针对1.2版本引发高中断的设备,或许能揭示问题症结所在。CPU 大部分时间用于用户空间吗?可以用 top 命令检查用户态是否消耗了较多 CPU 资源。哪个程序占用了最多的 CPU?借助 top 命令的进程排序功能,可以找出消耗大量 CPU 的程序。该程序是在内核模式下还是用户模式下运行时间更长?通过 time 命令观察程序在内核与用户空间的时间分配,其中一方不一定需要占据绝对优势。如果程序在核心上消耗的时间多于四分之一,那么核心的检查也应是关键点。程序具体在哪些系统接口上耗费了较多时间?借助 strace 或 oprofile 工具来观察程序调用了哪些系统接口,并识别出主要消耗时间的接口。可以通过减少接口调用频次,或者换成效率更高的接口来改善性能。程序又是在哪些函数内部消耗了时间?借助 ltrace 或 oprofile 找出耗费时间最多的函数,若函数被频繁调用,需检查是否存在冗余调用,例如在 for 循环的条件里反复调用某个函数,或者在 debug 日志中通过调用该函数获取字符串序列。如果单次调用耗时过长,需借助 oprofile 或 cachegrind 工具,检查函数中是否存在频繁执行却导致缓存大量未命中的代码段,可尝试优化数据结构,或改进代码逻辑,以提升热点代码的缓存命中率,04、内存使用是否出现异常?
借助 top、vmstat、procinfo 这类工具判断内存占用是否超出正常范围,同时发现内存交换区域持续在增大。
内存占用是否在增长?可以用 slabtop 来检查。需要了解内存的种类。通过 slabtop 对内存使用情况进行排序。可以识别出占用内存较多的对象名称。借助检索特定分配主体标识(比如 inode_cache),可以明确其关联的文件或所属模块,进而探究内存分配的缘由。进程是否在扩充内存?可借助 top 或 ps 按内存消耗排序,并检视 rss 等指标,判断进程物理内存是否增长。进程所涉内存种类为何?需查阅 /proc/
使用/status指令可以检查内存的运用状况。如果VmExe数值偏高,表示可执行文件本身占用了较多空间,需要找出哪些函数的文本部分比较庞大。当VmLib数值很高时,说明程序依赖了众多或者单个体积较大的共享组件,需要识别是哪些库引起了VmLib数值的显著增长。假如VmData数值偏大并且持续上升,意味着进程的数据区域或堆正在不断扩展。要查明哪些函数消耗了大量的栈内存。借助 gdb 对进程进行附加,依据回溯链信息推算当前栈指针与前一个栈指针的间距,该间距即为函数的栈空间大小,筛选出栈空间较大的函数。哪些函数在运行时申请了较多堆内存?运用 memprof 工具识别那些分配了堆内存的函数,并监视哪些进程的堆内存持续增长,从而判断是否存在不恰当的内存申请或内存泄漏现象。哪些库的体积相对庞大?通过 /proc/
通过查看进程加载的共享库信息,可以了解各个库的占用空间,进而判断是否有可能用更小的版本替代体积过大的库文件,或者将不同进程使用的相同库文件合并,以减少内存占用,哪些库函数占用的内存较多,如果进程的可执行文件本身体积较大,那么在内存中加载后也会消耗更多空间。借助 nm 指令能够对符号进行大小排序,从而识别出文本段体积较大的函数,并判断是否可以将其移除或压缩。若发现共享内存占用持续攀升,应运用 ipcs 命令检视共享内存详情,留意是否存在异常庞大的实例,或是共享内存总量呈现持续增长趋势。需要查明是哪个程序在使用共享内存,此时可借助 ipcs -p 命令,查询到具体创建并运用共享内存的进程信息。针对内存共享量过大的状况,需要审视其代码部分,判断内存分配是否得当。对于共享内存数量持续上升的情况,要排查是否存在生成后未能及时清除的问题。
05、磁盘 I/O 使用有问题?
执行 iostat 命令,检测平均延迟时长,延迟时长越长,代表磁盘负载越重。
哪个程序在操作磁盘?借助 iotop 确定高 IO 的程序。这个程序具体访问了哪些文件?借助 strace 追踪该程序与文件操作相关的系统调用,审视其调用细节和耗时情况,识别出耗时的读写动作。再根据其使用的文件描述符 fd 回溯到磁盘上的具体文件,明白为何需要执行这些读写,并探究是否能够进行改进。06、网络 I/O 使用有问题?
借助 ethool 检查网卡的上限容量,同时利用 iptraf 确认端口数据传输是否已满。
网络设备出现错误了吗?可以用 ifconfig/ip 命令检查网络接口有无错误发生,如果发现错误,很可能是硬件设置不当,需要联系网络管理员协助处理。网络设备传输的数据类型是什么呢?可以用 iptraf 命令查看数据类型(包括协议和端口号)。当前是否有程序在处理这种类型的数据?借助 netstat 检查有无程序经过这个网络接口传输数据,哪个远端机器发出了数据包?倘若没找到特定程序在处理这些数据,或许存在来自网络其他节点的恶意访问。可借助 etherape 或 wireshark 进行数据流追踪,或者联系网络管理员了解情况。哪个网络连接在接收数据?明确了负责管理流量的程序之后,借助 strace 或 lsof 工具,可以识别出引发这些数据交互的具体网络端口。