遇到 Linux CPU 告警,最稳妥的做法是先区分是应用计算密集还是系统调度问题,确认瓶颈类型后再针对性调整进程优先级或代码逻辑,避免盲目重启或扩容。
核心结论:CPU 高负载不一定是计算能力不足,更多时候是进程调度、锁竞争或外部依赖等待导致的,优先定位消耗最高的进程和线程。
- 定位:使用 top 和 mpstat 区分用户态、内核态和等待 IO 的时间占比。
- 分析:针对异常进程使用 pidstat 或 perf 锁定具体线程和函数调用。
- 验证:调整优先级或代码后,观察负载曲线是否平稳且业务延迟恢复正常。
快速定位瓶颈
使用 top 命令查看第一行信息。关注 us(用户空间)、sy(内核空间)和 wa(IO 等待)。
top -n 1
%Cpu(s): 2.5 us, 1.0 sy, 0.0 ni, 95.0 id, 1.5 wa, 0.0 hi, 0.0 si, 0.0 st示例分析:如果 wa 超过 30%,问题通常在磁盘或网络,而非 CPU 计算能力,此时扩容 CPU 无效。如果 us 过高,说明应用代码计算密集;如果 sy 过高,通常意味着频繁的系统调用或驱动问题。
在 top 界面按 P 键按 CPU 使用率排序,找到占用最高的 PID。记录该 PID,然后使用 pidstat -p <PID> -u 1 观察该进程是主要消耗在用户态还是内核态。
深入线程与代码级分析
找到占用最高的进程后,需要进一步定位到线程和代码行。
1. 定位热点线程
使用 top -H -p <PID> 查看该进程下的线程占用情况。找到占用最高的线程 ID(TID)。
2. 转换线程 ID
将十进制 TID 转换为十六进制,用于后续堆栈查找:
printf "%x\n" <TID>3. 查看代码堆栈
如果是 Java 应用,使用 jstack 配合十六进制 TID 查看堆栈:
jstack -l <PID> | grep -A 30 <十六进制 TID>如果是 C/C++ 或其他原生应用,可使用 perf 查看函数热点:
# -H 显示线程信息,-p 指定进程
perf top -p <PID> -H注意:在生产环境开启 perf 采样本身会消耗少量 CPU,高负载时需谨慎控制采样频率,避免雪崩。
4. 优化调整
如果是计算密集且业务允许,可使用 renice 调整优先级;如果是多核环境下的缓存命中率问题,可考虑使用 taskset 绑定 CPU 亲和性。但请注意,绑定 CPU 可能导致调度不均,需在小范围验证。
实战案例:Java 应用 CPU 飙高排查
某线上 Java 服务 CPU 持续 100%。
top发现 PID 12345 占用最高。top -H -p 12345发现 TID 12346 占用最高。printf "%x\n" 12346得到十六进制303a。jstack -l 12345 | grep -A 30 303a发现该线程卡在某个正则表达式匹配循环中。- 优化代码后,CPU 恢复正常。
验证与指标参考
优化操作后,保持监控窗口观察至少一个业务周期。使用 vmstat 1 查看系统级指标。
procs ---------`--memory----------` -`--swap--` ---`--io----` -system-- ----`--cpu-----`r b swpd free buff cache si so bi bo in cs us sy id wa st1 0 0 102400 81920 204800 0 0 0 0 500 2000 10 5 85 0 0指标参考范围:
- cs (context switch):上下文切换。通常每秒几千次是正常的,如果持续超过 10000-20000,说明线程竞争严重。
- in (interrupts):中断数。网卡包处理不均可能导致某核中断过高,检查网卡多队列配置。
- 业务延迟:观察业务侧的响应延迟(Latency)是否回归正常基线。如果 CPU 使用率下降但业务变慢,说明可能是限制了必要的计算资源,需回滚调整。
常见误区
- 混淆 Load 和 CPU 使用率:Load 高但 CPU 空闲,通常是 IO 瓶颈,此时优化 CPU 无效。
- 盲目杀进程:某些高 CPU 占用可能是正常的批量任务,直接 kill 可能导致数据不一致或任务重试风暴。
- 忽略软中断:如果
si(软中断)过高,可能是网络包处理不均,需要检查网卡多队列配置而非应用代码。
参考来源
- Brendan Gregg's Performance Blog, "Linux Performance Analysis in 60,000 Milliseconds", http://www.brendangregg.com/blog/2017-05-15/linuxperf.html
- Linux Man Pages, "top - display Linux processes", https://man7.org/linux/man-pages/man1/top.1.html
- Linux Man Pages, "pidstat - Report statistics for Linux tasks", https://man7.org/linux/man-pages/man1/pidstat.1.html
原文链接:https://www.zjcp.cc/ask/10932.html
