资讯动态

Linux服务器CPU使用率过高排查:从top到火焰图的完整实战指南

发布时间:2026/8/22 9:17:04 来源:尧图企业网站定制
1. 问题引入当你的Linux服务器开始“喘不过气”做运维或者开发的朋友估计都经历过这种心跳加速的时刻监控告警突然响了提示某台服务器的CPU使用率长时间飙到90%以上甚至直接100%。远程连上去整个系统响应慢得像蜗牛敲个命令都要等半天。这时候你脑子里第一个蹦出来的念头可能就是“到底是哪个进程在搞鬼”CPU使用率过高在Linux环境下是一个经典且高频的故障场景。它可能源于一个失控的应用程序、一个存在死循环的脚本、糟糕的配置甚至是底层系统的资源竞争。如果不能快速、准确地定位到问题的根源轻则影响服务响应重则可能导致系统崩溃业务中断。网上有很多零散的命令介绍比如“用top看看”、“ps一下”但真正到实战排查时往往发现命令输出信息繁杂不知从何下手或者解决了表面问题根源却还在那里过一阵子又卷土重来。今天我就结合自己多年在线上环境处理这类问题的经验给大家梳理一套从“现象感知”到“根因定位”的完整排查方法论。我们不止要会用top和ps更要理解它们输出的每一个字段背后的含义并学会组合使用pidstat、perf、strace等更强大的工具像侦探一样层层深入最终锁定那个消耗CPU的“元凶”。无论你是刚接触Linux的新手还是有一定经验的工程师这套方法都能让你在下次面对CPU告警时心中不慌手中有术。2. 排查工具箱核心命令深度解读工欲善其事必先利其器。在Linux世界里我们拥有一套强大的内置工具集来洞察系统的运行状态。很多人只知道top但其实每个工具都有其独特的视角和适用场景。理解它们是高效排查的第一步。2.1 全局视野top/htop命令的核心指标解读top命令是绝大多数人的第一选择它提供了一个动态更新的系统资源使用视图。但看top不能只看第一行的“%Cpu(s)”和进程列表里的“%CPU”我们需要读懂更多信息。首先看汇总行%Cpu(s):这一行是核心。我们常说的CPU使用率在这里被细分为多个维度us(user): 运行用户空间进程所花费的时间百分比。如果你的应用是Java、Python、Nginx等它们的正常运算就体现在这里。sy(system): 运行内核空间进程所花费的时间百分比。系统调用、中断处理、内核线程如kswapd的活动在这里。ni(nice): 运行被调整过优先级nice值的用户进程时间百分比。通常很低。id(idle): CPU空闲时间百分比。这是你最希望看到的数字越高说明系统越“轻松”。wa(IO-wait): CPU等待I/O通常是磁盘I/O完成的时间百分比。这是一个关键指标。如果wa很高而us和sy不高说明CPU没事干都在等磁盘瓶颈在存储I/O而不是CPU计算本身。hisi(hardware/software IRQ): 处理硬中断和软中断的时间。网络包处理频繁时si可能会升高。st(steal): 在虚拟化环境中被宿主机“偷走”的时间。如果你的虚拟机CPU使用率很高且st值也高说明物理主机资源竞争激烈。如果ussy持续高于80%基本可以确定存在计算密集型进程。如果wa异常高则需要转向I/O排查。其次看进程列表按ShiftP可以按CPU使用率排序。重点关注PID: 进程号后续所有操作的依据。USER: 进程所有者。是root、mysql还是www-data这能帮你快速缩小范围。%CPU: 该进程占用单个CPU核心的百分比。注意在多核系统上这个值可以超过100%。例如一个单线程进程死循环在8核机器上可能显示%CPU为100%这意味着它占满了一个核心。如果是400%则意味着它几乎占满了4个核心。TIME: 进程自启动后累计使用的CPU总时间。如果一个进程%CPU不高但TIME非常巨大说明它是一个长寿进程长期在消耗CPU。COMMAND: 进程的命令行。这是识别进程的关键。实操心得我强烈推荐使用htop替代原生的top。它颜色更友好支持鼠标点击表头排序查看进程树按F5的功能在排查“子进程爆掉”的问题时尤其好用。你可以一眼看出哪个父进程派生了一堆消耗CPU的子进程。安装也很简单apt install htop(Debian/Ubuntu) 或yum install htop(RHEL/CentOS)。2.2 进程快照ps命令的精准定位top是动态监控而ps则是拍摄一张静态的快照更适合精确获取某一时刻的进程信息或者进行脚本化处理。一个非常实用的组合是查看某个高CPU进程的详细信息及其线程# 查看指定PID进程的详细信息包括启动命令、内存、CPU等 ps -fp PID # 查看指定PID进程下的所有线程LWP的CPU使用情况-L参数是关键 ps -Lo pid,tid,pcpu,psr,comm -p PID第二条命令解释-L: 显示线程Light Weight Process。pid: 进程ID。tid: 线程ID在进程内唯一。pcpu: 该线程的CPU使用率。psr: 该线程当前运行在哪个CPU核心上。comm: 线程的命令名。通过这个命令你可以发现是不是进程内的某一个特定线程比如一个垃圾回收线程或者一个工作线程在疯狂消耗CPU而不是整个进程。另一个常用技巧是直接找出消耗CPU最高的前10个进程ps aux --sort-%cpu | head -11head -11是因为第一行是标题行2.3 专业 profilingpidstat 与 vmstatpidstat是systat工具包的一部分它能提供比ps更细粒度和周期性的进程资源统计是分析CPU问题的利器。# 每2秒采样一次共采样5次并显示进程的CPU使用情况 pidstat -u 2 5 # 更详细地查看某个特定进程的详细统计包括用户态/内核态CPU、等待CPU时间等 pidstat -urd -p PID 2 5-u表示CPU-r表示内存-d表示磁盘I/O。pidstat的输出会明确区分进程在用户态(%usr)和内核态(%system)的CPU消耗这对于判断问题是应用逻辑问题还是系统调用频繁导致的内核问题非常有帮助。而vmstat则提供了系统级别的整体概览重点看procs和cpu列vmstat 2 5r(run queue): 等待运行的进程数。如果这个值持续大于CPU核心数说明系统负载过高进程在排队等CPU。us,sy,id,wa: 同top中的含义。注意事项pidstat和vmstat的第一个参数是采样间隔第二个是采样次数。在问题发生时快速运行这些命令收集数据比只拍一张ps的快照更能反映趋势。3. 进阶诊断从进程到代码热点通过top或pidstat找到消耗CPU最高的进程PID后战斗才刚刚开始。我们需要知道这个进程内部到底在执行什么函数是什么代码逻辑在吃CPU。这就需要更进阶的工具。3.1 系统调用追踪strace 与 perf topstrace主要用于跟踪进程执行的系统调用。如果高CPU是由于频繁的I/O操作如读/写文件、网络通信、进程间通信或大量的内存分配brk,mmap导致的strace将是照妖镜。# 跟踪一个已运行进程的系统调用并统计调用次数和时间 strace -c -p PID # 跟踪进程并输出到文件便于分析 strace -o /tmp/strace.log -T -tt -p PID-c选项会在跟踪结束后生成一个漂亮的统计报告列出所有调用的系统调用、次数、错误次数和耗时。如果你发现read/write、poll/epoll_wait、futex常与锁相关等调用异常频繁或耗时极长那就找到了方向。-T -tt会为每个调用加上时间戳和耗时适合分析延迟。但strace有个明显缺点它本身开销较大会显著拖慢被跟踪进程的速度不适合在生产环境长时间使用。perf top则是一个性能分析“神器”。它从CPU的硬件性能计数器层面进行采样告诉你CPU时间到底花在了哪些函数上无论是用户态函数还是内核函数。它开销相对较小更适合生产环境。# 实时查看系统范围内消耗CPU最高的函数 perf top # 查看指定进程的CPU热点 perf top -p PID # 使用更直观的界面如果支持 perf top --stdio运行perf top后你会看到一个实时更新的列表类似top但显示的是函数名、所在的共享库如[kernel.kallsyms]、[java]、libc-2.17.so以及它占用的CPU比例。如果你看到一个像[.] _int_malloc或[.] __GI___epoll_wait这样的函数名列前茅那问题就很具体了可能是内存分配频繁或者网络事件循环空转。3.2 火焰图可视化性能瓶颈的终极武器perf top的输出是文本的对于复杂的调用关系不够直观。火焰图Flame Graph正是为了解决这个问题而生。它能将perf采集到的堆栈信息生成一张SVG图片横向表示调用栈的宽度即消耗CPU的时间比例纵向表示调用深度。一眼就能看出“火苗”最宽的地方就是性能瓶颈所在。生成火焰图的步骤采集数据使用perf record采样。# 对指定PID采样30秒 perf record -F 99 -p PID -g -- sleep 30-F 99表示每秒采样99次-g表示记录调用链堆栈sleep 30表示采样30秒。生成报告使用perf script将数据转换为通用格式。perf script out.perf生成火焰图使用Brendan Gregg提供的脚本需下载FlameGraph工具包。# 假设FlameGraph工具包在 /opt/FlameGraph /opt/FlameGraph/stackcollapse-perf.pl out.perf out.folded /opt/FlameGraph/flamegraph.pl out.folded cpu_flame.svg然后将cpu_flame.svg用浏览器打开你就可以交互式地查看哪个函数调用路径消耗了最多的CPU时间。实操心得火焰图是给开发人员看的最有力证据。当你把一张显示某个业务函数-JSON解析-内存复制这条路径特别宽的火焰图扔给开发同事时他们立刻就能明白优化点在哪里比说一百句“CPU高了”都管用。对于Java应用还可以使用async-profiler工具它能生成包含Java方法、Native方法乃至内核函数的一体化火焰图对JVM应用排查尤其友好。3.3 针对特定运行时的工具如果你的应用是Java那么JDK自带的工具是首选jstack: 用于抓取Java进程的线程堆栈。如果CPU高是因为某个线程死循环jstack可以看到这个线程正在执行什么Java方法。jstack PID jstack.log在jstack输出中查找RUNNABLE状态的线程看其堆栈信息。如果同一个业务方法反复出现那就是嫌疑犯。jstat -gcutil: 查看GC情况。如果频繁Full GC也会导致CPU飙升因为GC线程会全力工作。观察FGCFull GC次数和FGCTFull GC时间是否在快速增长。对于Go程序可以使用pprof# 通过HTTP端点如果程序开启了获取profile go tool pprof http://localhost:6060/debug/pprof/profile?seconds30 # 或者对运行中的程序直接采样 curl -sK -v http://localhost:6060/debug/pprof/profile?seconds30 cpu.pprof go tool pprof cpu.pprof4. 分类排查实战常见场景与根因分析掌握了工具我们还需要将现象与可能的原因关联起来。CPU高通常可以归结为以下几类每一类的排查侧重点不同。4.1 用户态CPU高us%异常这通常是应用程序自身逻辑问题导致的。排查思路如下确认进程通过top找到%CPU高且属于用户态us的进程。定位线程使用ps -Lo pid,tid,pcpu -p PID或top -H -p PID查看该进程内哪个线程最耗CPU。记下线程IDTID。分析线程堆栈Java应用用jstack PID导出堆栈将十进制的TID转换为十六进制printf \%x\n\ TID然后在jstack输出中搜索这个十六进制ID查看该线程在做什么。C/C/Go等Native应用使用gdb附加到进程gdb -p PID然后使用thread apply all bt打印所有线程堆栈或者使用perf工具采样。解读堆栈查看消耗CPU的线程堆栈顶部的函数。常见的可疑点包括死循环比如while(true)中没有睡眠或等待条件。密集计算复杂的算法、正则表达式匹配特别是回溯过多的正则、加密解密操作。低效的逻辑在循环内做重复的数据库查询、序列化/反序列化如JSON/XML解析。案例曾遇到一个API服务CPU飙升perf top显示[.] json_parse函数占用极高。用strace查看发现该进程在频繁地read一个小文件。最后定位到代码中每次请求都在循环里读取并解析同一个巨大的JSON配置文件而不是缓存解析结果。将配置文件加载到内存缓存后CPU使用率立刻恢复正常。4.2 内核态CPU高sy%异常高内核态CPU意味着进程在执行大量系统调用或者内核自身在处理繁重任务。排查思路确认现象top显示sy百分比远高于平时甚至超过us。使用pidstatpidstat -u -p PID 1查看该进程的%system是否很高。使用strace或perfstrace -c -p PID统计系统调用。关注futex锁竞争、epoll_wait网络、read/writeI/O、clone创建进程/线程等调用的次数和耗时。perf top -p PID查看内核函数热点如[k] _raw_spin_lock自旋锁频繁出现往往意味着锁竞争激烈。检查系统级活动上下文切换使用vmstat或pidstat -w查看cswch/s自愿上下文切换和nvcswch/s非自愿上下文切换。如果每秒上下文切换次数上万甚至更高说明系统在频繁切换进程/线程开销巨大。这可能是因为线程数过多ps -eLf | wc -l或者锁竞争导致线程频繁休眠/唤醒。中断使用cat /proc/interrupts查看中断分布。如果某个特定的网络或存储设备中断异常高可能是硬件或驱动问题。案例一个多线程日志服务sy高达60%。strace统计显示futex调用次数惊人。perf top显示[k] futex_wait和[k] futex_wake占主导。结合代码分析发现日志写入时使用了全局锁所有工作线程写日志都要竞争这把锁导致大量线程阻塞和唤醒。改为线程本地缓冲异步写入后sy降至正常水平。4.3 I/O等待高wa%异常导致的CPU“假高”这种情况非常具有迷惑性。top显示CPU使用率接近100%但仔细看发现waI/O等待占了绝大部分us和sy其实很低。这意味着CPU很闲但进程都在等I/O主要是磁盘I/O。排查思路确认瓶颈top中wa值高是首要标志。使用iostat这是诊断I/O问题的核心工具。iostat -x 1 5关注%util设备利用率接近100%表示设备饱和和await平均I/O等待时间单位毫秒。如果await远高于正常值例如从几ms飙升到几百ms说明磁盘响应缓慢。定位高I/O进程使用pidstat或iotop。pidstat -d 1 5 # 或者使用需要sudo的iotop sudo iotop查看哪个进程的kB_rd/s读速率或kB_wr/s写速率很高。分析进程行为对高I/O进程使用strace -e traceread,write -p PID或者使用lsof -p PID查看它打开了哪些文件。根因通常包括大量顺序写或随机读如数据库没有索引的全表扫描、日志文件疯狂写入。磁盘性能瓶颈使用了低速的云盘、RAID卡缓存策略不当、磁盘已满。内存不足导致频繁交换swap如果siswap in和soswap out在vmstat中不为0且wa高很可能是内存不足系统在频繁换页。用free -h确认。案例一个MySQL服务器CPU告警top显示wa超过70%。iostat发现sdb盘的%util持续100%await高达300ms。iotop定位到是mysqld进程在大量写。检查发现是慢查询日志slow log没有关闭且general_log被意外开启导致所有查询都写入磁盘。关闭不必要的日志后wa降至个位数。5. 系统性排查清单与预防措施经过一系列工具排查定位到问题并解决后我们还需要形成系统性的方法并思考如何预防。5.1 线上问题快速响应清单当收到CPU告警时可以按照以下清单快速操作保存现场信息保存全局状态立即执行top -b -n 1 /tmp/top_$(date %s).log和vmstat 1 5 /tmp/vmstat_$(date %s).log。定位问题进程ps aux --sort-%cpu | head -20 /tmp/ps_$(date %s).log。深入分析目标进程如果找到可疑PID例如12345pidstat -urd -p 12345 1 3 /tmp/pidstat_12345_$(date %s).logps -Lo pid,tid,pcpu,psr,comm -p 12345 /tmp/threads_12345_$(date %s).log如果条件允许perf record -F 99 -p 12345 -g -- sleep 30并尽快将perf.data文件归档。对于Javajstack 12345 /tmp/jstack_12345_$(date %s).log检查系统负载uptimesar -q 1 3查看负载队列。检查I/Oiostat -x 1 3 /tmp/iostat_$(date %s).log。检查网络sar -n DEV 1 3查看网络接口吞吐量。这些快照信息是事后分析的黄金资料尤其在你可能需要重启服务来快速恢复业务时。5.2 长效监控与预防建议被动排查不如主动预防。建立完善的监控体系至关重要基础监控监控系统级别的CPU使用率分us、sy、wa、id等、负载load average、内存、磁盘I/O和网络流量。设置合理的告警阈值如ussy持续5分钟85%告警。进程级监控对关键业务进程如Nginx, MySQL, Java应用监控其自身的CPU、内存使用量。很多监控系统如PrometheusNode Exporter可以做到。应用内埋点在应用程序中集成APM应用性能监控工具如SkyWalking, Pinpoint, 或商业产品。它们可以自动捕获慢事务、慢SQL、异常方法调用链并生成类火焰图能在问题发生前或发生时提供最直接的代码级洞察。日志与链路追踪确保应用程序日志记录关键操作的耗时并集成分布式链路追踪以便在出现性能问题时能快速定位到是哪个服务、哪个接口、哪条数据库查询慢了。容量规划与压测定期进行压力测试了解系统的容量边界。根据业务增长趋势提前进行资源扩容或代码优化。最后的小技巧对于临时缓解在万不得已时可以使用renice调整进程优先级或者使用cpulimit工具来限制某个进程的CPU使用率上限为排查争取时间。但这只是权宜之计根本还是要找到并修复问题源头。# 降低进程的优先级nice值增大从-20到19值越大优先级越低 renice 10 -p PID # 使用cpulimit限制进程CPU使用率不超过50% cpulimit -p PID -l 50CPU使用率过高排查是一个从宏观到微观、从现象到本质的推理过程。它考验的不仅是对命令的熟悉程度更是对系统原理、应用架构和编程逻辑的理解深度。希望这套结合了工具使用、场景分析和实战经验的排查思路能成为你工具箱里一件称手的武器。下次再遇到CPU告警不妨按这个流程走一遍你可能会发现解决问题本身也是一种乐趣。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价