首页/云/云与容器速查/容器 CPU 占用高排查

容器 CPU 占用高排查

容器吃满 CPU:先用 stats/top 定位到进程,再看是忙等、死循环还是限流假象;cgroup 的 cpu.stat 能看出 throttling,区分『真忙』与『被限速』。

云与容器速查云更新于 2026-10-13

先分清真忙与限速

容器 CPU 占用高的排查要分两步:先定位到具体容器与进程,再判断是「真的在计算」还是「被限速」。这是最容易混淆的一点:被限速时进程并不会崩溃,只是在每个周期内被暂停一部分时间,表现为响应变慢,而 CPU 使用率看起来仍然接近上限。cgroup 的 cpu.stat 能直接给出限流次数与累计限流时长。

基本信息

定位容器docker stats --no-stream,或集群侧的用量视图
定位进程docker top 看容器内进程,或在容器内按 CPU 排序查看
限流检查cgroup 的 cpu.stat,关注限流次数与累计限流时间
常见根因死循环与忙等、正则回溯、GC 频繁、日志风暴、密集加解密
抓现场手段线程栈与语言级性能剖析工具,用于还原热点
宿主侧干扰CPU 争抢指标偏高说明宿主资源被其他负载占用

指标读法

指标含义判断方式
CPU 使用率贴近配额容器长期贴着上限运行需进一步区分真忙还是被限速
限流次数累计被限流的周期次数持续增长说明配额不足或存在突发
累计限流时间被限流的总时长与运行总时长对比可判断影响程度
宿主争抢时间被其他负载占用的 CPU 时间容器内看不到,只能在宿主侧观察
上下文切换次数线程与进程切换频率切换高而 CPU 不高时方向要另查

典型使用场景

  • 单个容器突然打满 CPU,导致同宿主其他服务变慢
  • 服务响应变慢但 CPU 看起来不高,怀疑被限速
  • 集群节点整体负载高,需要把压力归因到具体容器
  • 压测过程中定位瓶颈,判断是配额不足还是代码热点
  • 批处理与定时任务占用 CPU,影响在线服务的响应时间

排查命令

排查命令
docker stats --no-stream myapp                    # 容器级用量
docker top myapp                                  # 容器内进程(宿主视角)
docker exec myapp sh -c 'ps aux --sort=-%cpu | head -10'
docker exec myapp cat /sys/fs/cgroup/cpu.stat 2>/dev/null | head   # 限流指标
docker inspect -f '{{.HostConfig.NanoCpus}}' myapp                 # 确认 CPU 配额
top -bn1 | head -5                                # 宿主侧看负载与争抢
CPU 突刺也可能是宿主资源争抢:这类指标在容器内看不到,需要在宿主侧观察。共享宿主的场景尤其常见,容器指标正常但业务变慢,答案往往在宿主那层。
把限流当成故障会误导方向:被限速时进程不会崩、日志里没有报错,只有「CPU 打满」这一个信号。看到高占用先确认是限流还是真在计算,再决定是调整配额还是改代码。

易错点

  • 把限流当故障:CPU 看似打满其实被限速,进程没崩只是变慢,排查方向被带偏
  • 只看宿主 CPU 总量:容器数量多时无法归因到具体服务,只能靠猜
  • 直接调高配额掩盖问题:死循环或正则回溯造成的高占用被放大到宿主,影响范围扩大
  • 忽略日志风暴与同步刷盘:IO 与 CPU 同时上升,只看 CPU 会漏掉真正的根因

数据来源与参考

  • Docker Docs:docker stats
  • Linux cgroup 文档(cpu.stat)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌