从“能跑”到“稳定运行三年不出大事故”
在 Kubernetes 上跑 Java,很多团队一开始都很自信:
不就是打个镜像、写个 YAML、起个 Pod 吗?
但真正上了生产你会发现, Java + K8s 是一场长期博弈 :
有的服务隔三差五被 OOMKilled
有的在高峰期内存飙升但 CPU 不高
有的滚动升级一半流量 502
有的 Pod 明明还活着,但已经“假死”
在 Kubernetes 上跑 Java,几乎所有团队都会经历同一个阶段:
一开始很自信,上线很顺利,半年后开始疲于救火。
最初的认知通常是这样的:
镜像能 build
Deployment 能起
Service 能通
压测也能过
于是大家会下意识地认为:
“Java + K8s 也就这么回事。”
但真正进入长期运行阶段后,问题开始慢慢出现。
这是一个典型的业务中台服务:
Spring Boot + JDK 17
日均请求量不高,但有明显高峰
对 RT 敏感(接口链路中段)
每次大促、批量任务都会被放大
部署方式非常“标准”:
resources: requests: cpu: "1" memory: "2Gi" limits: cpu: "2" memory: "2Gi"
JVM 参数也“很传统”:
-Xms2g -Xmx2g
上线初期,一切正常。
没有任何 Java OOM 日志,只看到:
Reason: OOMKilled
重启之后又能跑。
第一次,大家认为是偶发;
第二次,认为是流量波动;
第三次,开始有人说“是不是 K8s 不稳定”。
监控上看到一个反直觉的现象:
CPU 使用率:40%~50%
内存接近 limit
RT 偶发性拉长
Full GC 偶尔出现
这时候,很多团队会犯一个错误:
👉
盲目加 Pod、副本翻倍
结果:
OOM 问题缓解了一点
但资源成本上来了
根因完全没解决
滚动发布时,偶发:
一半 Pod 已 Ready
另一半一直重启
用户侧看到 502
这类问题最要命的地方在于:你很难在测试环境复现。
这个阶段,我给团队下了一个结论:
这不是 Kubernetes 的问题,也不是 Java 的问题,而是 JVM 没有被当成“运行在容器里的 JVM”来治理。
换句话说:
我们一直在用“物理机时代的 JVM 思维”,跑在“强边界的容器环境里”。
在容器里,JVM 实际消耗的内存是:
Heap +Metaspace +Direct Memory +Thread Stack +JVM 自身开销 +OS Buffer
而 Kubernetes 只认一件事:
总和 > memory limit → 直接 OOMKilled
这和物理机时代 完全不同 。
这是最关键的一步。
# 删除 -Xms2g -Xmx2g
改为:
-XX:+UseContainerSupport -XX:MaxRAMPercentage=70
设计逻辑:
容器 limit = 2Gi
Heap ≈ 1.4Gi
剩余 600M 给非堆和 OS
👉 这是“容器优先”的 JVM 设计思路
重新定义资源策略:
requests: cpu: "800m" memory: "2Gi" limits: cpu: "2" memory: "2.5Gi"
不是一拍脑袋就给值了,而是基于监控数据:
稳态内存 ≈ 1.6Gi
峰值 ≈ 1.9Gi
非堆波动 ≈ 300~400M
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/heapdumps
架构原则:
线上 OOM,必须留下“现场证据”。
没有 Dump 的 OOM 排查,本质是猜谜。
-XX:+ExitOnOutOfMemoryError
这一步是为 Kubernetes 设计的,而不是 JVM。
JVM 出问题
Pod 立刻退出
K8s 自动拉起新实例
这是 平台化自愈的基础 。
Readiness :只判断是否接流量
Liveness :只判断是否需要重启
避免一个接口干两件事。
java程序启动慢是事实。
没有 Startup Probe 的结果只有一个:
👉
启动期被误杀
捕获 SIGTERM
停止接新请求
等待正在处理的请求完成
这是避免滚动升级 502 的根本手段。
通过 Micrometer 暴露:
Heap / Non-Heap
GC 次数与耗时
线程数变化
架构层面的价值是:
OOM 不再是突发
内存泄漏有趋势
GC 抖动能提前感知
在 Java 场景下:
GC 抖动
内存压力
线程阻塞
往往不会直接反映到 CPU。
最终策略是:
CPU + RT
内存趋势
请求队列长度
这套服务上线后:
OOM 从“偶发事故” → “可预测事件”
滚动升级 502 消失
资源使用率下降 20%+
再没有半夜被 OOMKilled 叫醒
真正起作用的不是某个 JVM 参数,而是这几个认知转变:
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70042969/viewspace-3110883/ ,如需转载,请注明出处,否则将追究法律责任。