Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

发布系统:滚动发布(Rolling Update)

一、什么是滚动发布?

滚动发布:

不停止整体服务 的情况下,逐个或分批替换旧版本实例为新版本,始终保证系统中有可用实例对外服务

一句话:

不停机、分批换版本

二、滚动发布的核心目标

  • 零停机(或感知极低)
  • 风险可控
  • 自动回滚
  • 服务连续可用

三、典型工作流程

旧版本实例 × N 正常服务
下线 1~K 个旧实例(摘流量)
启动新版本实例
健康检查通过
加入负载均衡
重复以上步骤
所有实例完成升级

关键点:

  • 先摘流量,再升级
  • 新实例健康后才接流量

四、滚动发布的前置条件(非常重要)

1️⃣ 服务必须是「无状态」

  • Session 不存本地
  • 文件不写本地
  • 状态放在 DB / Redis / 对象存储

❌ 有状态服务直接滚动 = 灾难

2️⃣ 必须有健康检查

  • HTTP health check
  • TCP 探测
  • 应用级自检

3️⃣ 支持优雅关闭(Graceful Shutdown)

  • 收到 SIGTERM 后:
  • 停止接新请求
  • 等待正在处理的请求完成
  • 再退出

五、滚动发布的关键控制参数

1️⃣ 发布批次大小

  • 一次下线几个实例?
  • 建议:
  • 小集群:1 台
  • 大集群:5%~20%

2️⃣ 发布节奏

  • 每批间隔时间
  • 是否等待监控稳定

3️⃣ 健康阈值

  • 成功率
  • 延迟
  • 错误率

六、Kubernetes 中的滚动发布(最常见)

Deployment 核心参数

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxUnavailable: 1
    maxSurge: 1

含义:

  • maxUnavailable:升级过程中,最多允许不可用的 Pod 数
  • maxSurge:最多允许额外创建的 Pod 数

示例:

  • 5 副本
  • maxUnavailable=1
  • maxSurge=1

-> 最多 6 个 Pod,至少 4 个可用

发布过程

  1. 创建新 Pod
  2. 新 Pod Ready
  3. 老 Pod 进入 Terminating
  4. 执行优雅关闭
  5. 逐个替换完成

七、滚动发布常见问题 & 风险

❌ 1. 请求中断

原因:

  • 没有优雅关闭
  • LB 未摘流量
  • readinessProbe 配置错误

解决:

  • 正确配置 readiness / liveness
  • 增加 terminationGracePeriodSeconds

❌ 2. 新版本有 Bug,已影响用户

滚动发布 ≠ 灰度

-> 全量仍然会被逐步影响

解决:

  • 结合 金丝雀发布
  • 或发布前压测 / 回滚机制

❌ 3. 数据库不兼容

  • 新版本依赖新字段
  • 老版本仍在跑

解决:

  • 数据库 向前兼容
  • 两阶段发布(先 DB,后代码)

八、滚动发布 vs 其他发布方式

发布方式 停机 风险 回滚速度 复杂度
滚动发布
蓝绿发布 极快
金丝雀 极低

九、滚动发布的最佳实践(重点)

  • 必须无状态
  • readinessProbe 决定是否接流量
  • livenessProbe 决定是否重启
  • 优雅关闭 ≥ 30s
  • 每一批都观察监控
  • 失败立即暂停发布
  • 结合限流、熔断
  • 发布窗口选低峰期

十、什么时候不适合滚动发布?

  • 有状态服务(如单实例数据库)
  • 强一致性写入服务
  • 大版本破坏性变更
  • 无法向前兼容的协议

十一、总结

滚动发布是默认方案,但不是万能方案。

它解决“不停机”,但不解决“新版本一定正确”。