现象定位
CPU 超过 limit 不会杀容器,而是按 CFS 周期强制限速:在周期内用满配额后,剩下的时间被挂起等待下一个周期。适用平台是 Kubernetes(底层由 cgroup 的 CFS 带宽控制实现)。它的特点是没有任何退出码、没有崩溃事件,只表现为延迟毛刺、QPS 上不去、GC 停顿变长。因此「高负载下的慢」在没有资源告警的情况下,第一件事就是查节流。
基本信息
| 适用平台 | Kubernetes,基于 Linux cgroup CFS 带宽控制 |
|---|---|
| 触发条件 | 容器在一个周期内消耗完 CPU 配额 |
| 观察指标 | container_cpu_cfs_throttled_periods_total、throttled_seconds_total |
| 关键区别 | CPU 超限节流不重启容器,内存超限则触发 OOM 杀进程 |
典型使用场景
- 接口延迟抖动:排查是否在流量高峰被节流
- 扩容判断:请求量与 CPU 配额对不上时先看节流指标再决定扩副本
- 模板纠错:把某个服务的小限额复制到了全量部署,导致集中节流
- 上线前压测:确认 limits 设置能支撑目标 QPS
- 节点密度评估:节点拥挤时即使没超 limit 也可能抢不到 CPU
观测路径
观测路径
# 容器内 cgroup v2 统计(需相应权限)
kubectl exec -it web-x -- cat /sys/fs/cgroup/cpu.stat
kubectl exec -it web-x -- cat /sys/fs/cgroup/cpu.max # 配额与周期
# Prometheus 常用指标
# container_cpu_cfs_throttled_periods_total / container_cpu_cfs_throttled_seconds_total
kubectl top pod web-x # 对照实际用量与 limit处置思路
处置思路
# 1) 评估并提高 limits,或为 Burstable 留出突发空间
# 2) 关注大并发与 GC 抖动时段:节流重灾区
# 3) 核对是否把 250m 这类小限额随着模板复制到了全量部署
kubectl get deploy web -o jsonpath='{.spec.template.spec.containers[*].resources}'
kubectl get pods -o custom-columns='NAME:.metadata.name,CPU_LIMIT:.spec.containers[0].resources.limits.cpu'现象与原因对照
| 现象 | 可能原因 | 核对方式 |
|---|---|---|
| 延迟毛刺无告警 | 高频短时超限被节流 | 看 throttled 指标曲线 |
| QPS 上不去 | limits 低于单实例能力上限 | 压测对比不加 limit 的版本 |
| 高峰集中变慢 | 低 requests 高密度部署导致抢 CPU | 看节点 CPU 水位与节流比例 |
| 偶发超时 | 周期边界效应,突发请求撞上配额耗尽 | 观察节流与超时的时间相关性 |
节流发生在毫秒级周期内,CPU 平均值很难反映,必须看 throttled 系列指标或容器内的 cgroup 统计。
配额严格时短突发请求容易被切分到多个周期执行,表现为 P99 明显高于 P50,这是典型的节流特征。