Pod 的 limits.cpu 是 2,启动日志里 JVM 识别到 64 个处理器,ParallelGCThreads 起了 100 多个,容器 CPU throttling 比例长期在 40%。乍看像缓存或者权限的锅,追下去往往不是。

java -XX:ActiveProcessorCount=2 -XX:ParallelGCThreads=2 \
  -XX:+UseG1GC -jar app.jar
cat /sys/fs/cgroup/cpu.stat | grep throttled
jcmd 21455 VM.info | grep -i processor

追下去是这么回事:JDK 8u191 之前不看 cgroup 的 CPU quota,直接读宿主机核数。GC 和 JIT 线程按 64 核开,实际只有 2 核可用,线程互相抢配额被限流。

「容器 CPU 感知」这类改动最怕改一半,回滚脚本先准备好,再动生产。接口问题先分清是没发出去、发出去了没收到,还是收到了处理失败。

偶发问题先统计频率,一小时几次和一天一次,查法完全不同。改完顺手把文档补一句,省得下次自己重新推一遍。

监控和日志的时间要对上,时区不一致会多绕很大一圈。临时改动用注释写上日期和原因,过两周自己都记不清为什么这么写。

动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

具体做法是,升级到 8u191 以上或 JDK 11 让 JVM 读 cgroup;加 -XX:ActiveProcessorCount=2 强制指定;GC 线程数用 -XX:ParallelGCThreads 显式限制;观察 throttled 指标确认是否下降。

验收就看一点,JVM 日志里看到的处理器数为 2 container_cpu_cfs_throttled_periods 明显下降。

作者 9823189