Java 部署:滚动更新(K8s RollingUpdate 策略)

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 不可用(整数或百分比)

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

组合写法maxSurgemaxUnavailable含义与适用场景资源峰值倍数推荐指数
1:1(最保守、安全)25%25%标准推荐写法,兼顾速度与稳定性≈1.25x★★★★★
激进型(追求最快上线)100%0%几乎瞬间完成,但资源翻倍,适合资源充裕集群≈2x★★★☆☆
极保守型(零中断优先)01(或 10%)一次只替换一个,适合对可用性要求极高的服务≈1.0x★★★★☆
内存敏感型(常见于 Java)125%控制峰值内存占用,适合 JVM 内存吃紧的场景≈1.1~1.2x★★★★☆
副本数很少(1~3副本)10小规模服务推荐,避免任何时刻副本数 < 期望值≈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 reset1. terminationGracePeriodSeconds ≥ 30~60s
2. preStop sleep 或调用 /shutdown 接口
readinessProbe 太快,流量提前进来502 / 慢请求initialDelaySeconds ≥ 启动时间 + 20s
使用 /health/readiness
JVM 老年代频繁 Full GCPod 频繁重启 / OOMKilled1. 使用 ZGC / Shenandoah
2. MaxRAMPercentage 70~80%
3. 降低 maxSurge
启动太慢,滚动更新卡住progressDeadlineSeconds 超时增加 progressDeadlineSeconds 到 900~1200
优化镜像分层
副本数少(1~2个)时短暂无服务maxUnavailable=25% 时仍断流maxUnavailable: 0
maxSurge: 1 或 100%

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

服务规模 / 场景replicasmaxSurgemaxUnavailableminReadySecondsterminationGracePeriodSeconds推荐 GC
小型内部服务(测试/开发)2~3100%02030ZGC / Epsilon
中型业务服务4~1025%25%30~4545~60ZGC / Shenandoah
高可用核心服务6+1~2145~6060~120ZGC
内存极度敏感(单 Pod 8GB+)任意125%6090ZGC + 限流

快速检查命令

# 查看当前 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 + 启动参数组合。

文章已创建 4915

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部