Linux

服务器 CPU 异常全场景总结

·9 分钟阅读·3594 字
📋 目录

服务器 CPU 异常全场景总结

核心概念 CPU 异常分为整机高负载、频繁抖动突刺、内核占用高、业务卡死四大类场景,覆盖物理机和容器环境。

分为四大类:整机CPU持续高负载、CPU频繁抖动突刺、CPU空闲但内核占用高、CPU低但业务卡死卡顿,覆盖物理机、虚拟机、K8s节点/容器场景。

1. 场景1:整机CPU长期满负载(top看到%Cpu0~100%,平均负载居高不下)

1.1. 现象

  1. top/htop 所有CPU核心占用80%~100%,load average远大于CPU核心数;
  2. 业务接口超时、请求堆积、TCP连接大量ESTABLISHED;
  3. 新进程创建缓慢、ssh登录延迟、命令执行卡顿;
  4. K8s节点会出现Pod调度失败、kubelet响应慢、探针超时Pod重启。

1.2. 根因分类

1.2.1. 1)用户态进程耗尽CPU(us高)

  • 业务程序死循环、无限递归、高频计算逻辑;
  • 日志疯狂打栈、全量查询无索引、大量正则模糊匹配;
  • 批量任务并发过高(ES聚合、Kafka批量消费、大数据计算);
  • 容器未配置limits,单Pod无限抢占节点CPU。

1.2.2. 2)内核态CPU暴涨(sy高)

  • 海量短连接、大量TIME_WAIT,conntrack表打满;
  • iptables/eBPF规则上万条,流量匹配消耗内核;
  • 磁盘IO阻塞、频繁缺页中断、swap频繁换入换出;
  • 大量进程创建销毁、僵尸进程未回收、频繁fork。

1.2.3. 3)软中断softirq飙高(si高)

网卡流量打满、小包风暴、DDOS攻击、CNI隧道封装解封装开销大。

1.2.4. 4)定时任务并发扎堆

crontab、日志切割、备份、数据库统计任务同一时刻触发。

1.3. 排查方案

  1. 定位占用最高进程
top # 按P按CPU排序,看PID、COMMAND
ps -aux --sort=-pcpu | head -10
  1. 容器环境定位Pod
kubectl top node
kubectl top pod -A --sort-by=cpu
  1. 区分用户/内核/软中断开销
mpstat -P ALL 1 # 单核心细分us,sy,si,iowait
vmstat 1
  1. 进程内部定位耗CPU代码
# 安装perf工具
perf top -g -p <PID> # 查看函数CPU占用,定位死循环/计算热点
# Java程序
jstack <PID>  # 线程栈,死循环线程
jstat -gc <PID> 1s # 频繁FullGC导致CPU高
  1. 网络软中断排查
cat /proc/softirqs # 看NET_RX/NET_TX暴涨
sar -n DEV 1 # 网卡流量带宽
  1. 临时缓解:限流、杀死异常进程、分批执行定时任务;长期优化代码、加资源限制。

2. 场景2:CPU周期性突刺、瞬间冲高后回落,整体平均不高

2.1. 现象

  1. 日常CPU 20%,每几分钟瞬间拉满100%几秒;
  2. 周期性接口毛刺、少量5xx、短暂延迟突增;
  3. 集群批量Pod同时重启、滚动更新同步触发重建。

2.2. 根因

  1. 定时任务:日志rotate、数据库定时统计、备份、ES段合并、Prometheus大量采集;
  2. JVM定时FullGC、Redis持久化RDB/AOF刷盘;
  3. K8s批量操作:批量重建Pod、reindex、分区迁移、快照备份;
  4. 流量潮汐:整点报表、定时上报埋点、定时同步数据。

2.3. 排查方案

  1. 监控拉取CPU时序曲线,确认突刺固定周期;
  2. 检查定时任务:crontab -l、系统定时日志/var/log/cron
  3. 中间件日志:ES段合并日志、Redis rdb持久化日志;
  4. Java应用监控GC曲线,确认GC和CPU尖峰对齐;
  5. 优化:分散定时任务执行时间、调低后台任务并发、限流后台合并/备份操作。

3. 场景3:内核CPU占用极高,用户业务CPU很低(sy字段高)

3.1. 现象

top中sy内核占用50%+,业务进程us很低,业务缓慢、无大量计算。

3.2. 根因

  1. 海量连接,nf_conntrack表溢出,内核频繁处理连接跟踪;
  2. iptables/Calico大量NetworkPolicy规则,数据包逐层匹配;
  3. 大量swap交换,内存不足频繁页面置换;
  4. 程序频繁创建销毁子进程,fork/exit系统调用频繁;
  5. 磁盘坏道、IO阻塞,内核等待IO产生大量中断;
  6. 老旧内核BUG、驱动异常。

3.3. 排查方案

# 查看连接跟踪表容量
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# 查看swap使用
free -h
vmstat 1 # si so 数值高代表频繁交换
# 查看系统调用开销
perf stat -p PID sleep 10
# 查看磁盘IO等待
iostat -x 1

优化:调大conntrack最大值、优化网络策略减少iptables规则、关闭swap、扩容内存、更换eBPF CNI替代iptables。

4. 场景4:软中断si占用CPU极高,业务几乎无消耗

4.1. 现象

mpstat中si占比极高,网卡流量大,小包多,网络延迟高。

4.2. 根因

  1. 业务海量小包收发(日志采集、MQ高频收发);
  2. 遭受网络DDOS、端口扫描;
  3. CNI IPIP/VXLAN隧道大量封装解封装;
  4. 网卡中断绑定不均衡,所有中断集中单个CPU核心。

4.3. 排查方案

cat /proc/softirqs
sar -n DEV 1 # 网卡每秒包量Pkt/s
# 查看中断亲和性
cat /proc/interrupts

优化:网卡多队列中断均衡、启用RSS分流、隧道切换BGP裸三层、防火墙拦截异常扫描流量。

5. 场景5:CPU空闲很高,但业务卡顿、响应缓慢(iowait高)

5.1. 现象

CPU整体空闲多,但%iowait数值很高,接口超时、数据库慢查询堆积。

5.2. 根因

  1. 磁盘IO打满,读写阻塞进程,进程挂起等待磁盘;
  2. 机械盘大量随机写、数据库刷脏页、日志疯狂落盘;
  3. 存储卷性能不足,云盘IOPS打满;
  4. ES段合并、大量批量写入抢占IO。

5.3. 排查方案

iostat -x 1
iotop # 定位占用IO最高进程

优化:更换SSD、拆分冷热数据、限流批量写入、调整刷盘策略、扩容存储IOPS。

6. 场景6:K8s容器专属CPU异常(节点空闲,单个Pod CPU打满)

6.1. 现象

节点总CPU不高,某一个Pod持续100%CPU;限制CPU后Pod频繁被限流、服务卡顿。

6.2. 根因

  1. Pod未配置limits,无限抢占节点CPU;
  2. 应用内部死循环、无限重试、频繁轮询;
  3. sidecar采集日志/metrics并发过高;
  4. 内核cgroup限流,Pod CPU被压制导致业务阻塞。

6.3. 排查方案

kubectl top pod
# 进入容器定位进程
kubectl exec -it podname -- top
kubectl exec -it podname -- perf top

优化:配置合理requests/limits、优化应用轮询逻辑、降低sidecar采集频率。

7. 场景7:CPU负载很高,但使用率低(load高,idle高)

7.1. 现象

load average远大于CPU核心数,但CPU idle空闲多。

7.2. 根因

load统计等待CPU/IO/锁的进程总数

  1. 大量进程阻塞在磁盘IO;
  2. 大量线程锁等待、数据库连接池耗尽、大量阻塞线程;
  3. 僵尸进程堆积未回收。

7.3. 排查方案

ps -ef | grep defunct # 僵尸进程
jstack / gstack 查看阻塞线程
iostat 查看IO等待

通用标准化排查步骤(任何CPU异常统一流程)

  1. 宏观指标:top/mpstat/vmstat 区分 us/sy/si/iowait/idle;
  2. 定位顶层占用:物理机找PID,k8s先定位Node/Pod;
  3. 细分来源:业务代码 / GC / 网络中断 / IO / 定时任务 / 内核规则;
  4. 深度追踪:perf查看函数栈、jstack/jstat分析Java、sar分析流量磁盘;
  5. 临时止损:限流、暂停定时任务、kill异常进程、扩容资源;
  6. 长期根治:代码优化、资源限制、架构拆分、内核参数调优。

关联文档