Java 应用在 Kubernetes 中的滚动更新(RollingUpdate)策略详解

滚动更新(RollingUpdate)是 Kubernetes Deployment 最常用的更新策略,几乎是 Java Spring Boot、Spring Cloud、Quarkus、Micronaut 等后端服务在生产环境的标准做法。

核心概念对比

策略类型 是否同时存在新旧版本 服务中断时间 资源峰值占用 回滚难度 Java 服务最常用场景
RollingUpdate 通常 0 中等~较高 容易 绝大多数生产环境首选
Recreate 有(秒~分钟) 较低 中等 数据库迁移、状态强绑定服务
Blue-Green 是(但手动控制) 接近 0 最高(双份) 容易 金融、对版本切换极度敏感场景
Canary 是(部分流量) 0 中等 中等 灰度发布、A/B 测试

Java 服务 90%+ 的场景最终都会选择 RollingUpdate

RollingUpdate 的两个核心控制参数

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge:       # 最多可以比期望副本数多多少个 Pod(可以是整数或百分比)
    maxUnavailable: # 更新期间最多允许多少个 Pod 不可用(整数或百分比)

最常见的几种组合(按推荐顺序):

组合写法 maxSurge maxUnavailable 含义与适用场景 资源峰值倍数 推荐指数
1:1(最保守、安全) 25% 25% 标准推荐写法,兼顾速度与稳定性 ≈1.25x ★★★★★
激进型(追求最快上线) 100% 0% 几乎瞬间完成,但资源翻倍,适合资源充裕集群 ≈2x ★★★☆☆
极保守型(零中断优先) 0 1(或 10%) 一次只替换一个,适合对可用性要求极高的服务 ≈1.0x ★★★★☆
内存敏感型(常见于 Java) 1 25% 控制峰值内存占用,适合 JVM 内存吃紧的场景 ≈1.1~1.2x ★★★★☆
副本数很少(1~3副本) 1 0 小规模服务推荐,避免任何时刻副本数 < 期望值 ≈2x(短暂) ★★★★☆

生产中最推荐的 Java 滚动更新模板(2025-2026 主流写法)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
spec:
  replicas: 6
  selector:
    matchLabels:
      app: order-service
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%           # 最多同时多出 1~2 个 Pod(6副本时最多多1~2个)
      maxUnavailable: 25%     # 最多允许 1~2 个 Pod 不可用
  minReadySeconds: 30         # Pod 就绪后至少等待 30s 才认为稳定
  progressDeadlineSeconds: 600
  revisionHistoryLimit: 10
  template:
    metadata:
      labels:
        app: order-service
    spec:
      terminationGracePeriodSeconds: 60   # 优雅终止时间(Java 应用建议 ≥ 30s)
      containers:
      - name: app
        image: registry.cn-hangzhou.aliyuncs.com/my-ns/order-service:1.2.3
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /actuator/health/readiness   # Spring Boot 3.x 推荐
            port: 8080
          initialDelaySeconds: 20
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 3
        livenessProbe:
          httpGet:
            path: /actuator/health/liveness
            port: 8080
          initialDelaySeconds: 60
          periodSeconds: 10
        resources:
          requests:
            cpu: 800m
            memory: 1.5Gi
          limits:
            cpu: 1500m
            memory: 2.5Gi
        env:
        - name: JAVA_OPTS
          value: "-XX:MaxRAMPercentage=75.0 -XX:+UseZGC -XX:ConcGCThreads=2"
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 15"]   # 给优雅停机留时间

Java 应用在滚动更新中常见的坑与解决办法

问题 表现 解决办法(优先级顺序)
优雅停机没做好,请求丢失 503 / connection reset 1. terminationGracePeriodSeconds ≥ 30~60s
2. preStop sleep 或调用 /shutdown 接口
readinessProbe 太快,流量提前进来 502 / 慢请求 initialDelaySeconds ≥ 启动时间 + 20s
使用 /health/readiness
JVM 老年代频繁 Full GC Pod 频繁重启 / OOMKilled 1. 使用 ZGC / Shenandoah
2. MaxRAMPercentage 70~80%
3. 降低 maxSurge
启动太慢,滚动更新卡住 progressDeadlineSeconds 超时 增加 progressDeadlineSeconds 到 900~1200
优化镜像分层
副本数少(1~2个)时短暂无服务 maxUnavailable=25% 时仍断流 maxUnavailable: 0
maxSurge: 1 或 100%

推荐的 Java 服务滚动更新参数参考表

服务规模 / 场景 replicas maxSurge maxUnavailable minReadySeconds terminationGracePeriodSeconds 推荐 GC
小型内部服务(测试/开发) 2~3 100% 0 20 30 ZGC / Epsilon
中型业务服务 4~10 25% 25% 30~45 45~60 ZGC / Shenandoah
高可用核心服务 6+ 1~2 1 45~60 60~120 ZGC
内存极度敏感(单 Pod 8GB+) 任意 1 25% 60 90 ZGC + 限流

快速检查命令

# 查看当前 rollout 状态
kubectl rollout status deployment/order-service

# 查看历史版本
kubectl rollout history deployment/order-service

# 回滚到上一个版本
kubectl rollout undo deployment/order-service

# 回滚到指定版本
kubectl rollout undo deployment/order-service --to-revision=3

# 暂停滚动更新(调试用)
kubectl rollout pause deployment/order-service

希望这篇内容能帮你把 Java 应用在 K8s 上的滚动更新策略理清楚。

你目前遇到的具体问题是?

  • 启动太慢导致滚动卡住?
  • 优雅停机没做好丢请求?
  • 内存峰值爆炸?
  • 小副本数场景下仍然断流?
  • 想做金丝雀 / 蓝绿?

告诉我具体场景,我可以给出更针对性的 yaml + 启动参数组合。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐