发布与回滚规范
灰度发布、回滚机制、零停机部署、发布审批
[Standard] 根据变更类型和风险等级选择发布模式:
| 发布模式 | 适用场景 | 风险 | 回滚速度 |
|---|---|---|---|
| 蓝绿部署 | 全量切换、重大版本 | 低 | 秒级 |
| 滚动发布 | 常规迭代 | 中 | 分钟级 |
| 灰度发布(金丝雀) | 高风险变更、新功能 | 低 | 秒级 |
| A/B 测试 | 产品验证、UI 改动 | 低 | 秒级 |
[Default] 核心服务每周至少发布 1 次,禁止长期积压变更后一次性大版本发布。小步快跑,降低单次变更风险。
[Caution] 禁止在以下时段发布:
- 法定节假日前 1 天及节假日期间
- 周五下午 18:00 之后
- 业务高峰期(如电商大促期间)
[Standard] 生产环境发布窗口:工作日 10:00-16:00,确保有充足的运维和研发人力值守。
[Standard] 灰度发布按以下比例逐步放量,每个阶段观察至少 15 分钟,无异常再进入下一阶段。
1% → 5% → 10% → 30% → 50% → 100%| 阶段 | 流量比例 | 观察重点 | 观察时长 |
|---|---|---|---|
| 金丝雀 | 1% | 错误率、核心接口响应时间 | 15 分钟 |
| 小流量 | 5% | 错误率、资源使用率 | 15 分钟 |
| 中流量 | 10% | 业务指标、依赖服务健康 | 15 分钟 |
| 大流量 | 30% | 全量监控指标 | 15 分钟 |
| 半量 | 50% | 与全量对比 | 15 分钟 |
| 全量 | 100% | 持续观察 30 分钟 | 30 分钟 |
[Standard] 灰度流量可按以下维度切分,根据业务场景选择:
| 维度 | 说明 | 示例 |
|---|---|---|
| 按用户 ID | 特定用户群体 | 用户 ID 尾数为 0 的用户 |
| 按地域 | 特定地区 | 北京、上海地区 |
| 按设备 | 特定终端 | iOS 16+ 设备 |
| 按请求头 | 自定义标识 | X-Gray: true |
| 按比例 | 随机百分比 | 10% 流量 |
Nginx 灰度示例(按请求头):
upstream backend_v1 { server 10.0.0.1:8080; }
upstream backend_v2 { server 10.0.0.2:8080; }
server {
location / {
if ($http_x_gray = "true") {
proxy_pass http://backend_v2;
}
proxy_pass http://backend_v1;
}
}K8s 金丝雀发布示例:
# 新版本 Deployment(金丝雀),仅 1 个副本
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service-v2
spec:
replicas: 1
selector:
matchLabels:
app: user-service
version: v2
template:
metadata:
labels:
app: user-service
version: v2
spec:
containers:
- name: user-service
image: registry.example.com/user-service:2.0.0
---
# Service 同时匹配 v1 和 v2,按副本数分配流量
apiVersion: v1
kind: Service
metadata:
name: user-service
spec:
selector:
app: user-service
ports:
- port: 80[Requirement] 灰度过程中出现以下任一情况,立即中止并回滚:
- 错误率 ≥ 1%(或高于基线 0.5 个百分点)
- 核心接口 P99 响应时间劣化 ≥ 50%
- 业务核心指标(下单量、支付成功率等)下降 ≥ 5%
- 出现 P0/P1 级故障
[Requirement] 每个版本发布前必须制定回滚方案,回滚操作必须在 5 分钟内完成。
[Caution] 回滚优先于定位问题。先回滚恢复服务,再排查根因。
| 回滚方式 | 适用场景 | 操作 | 耗时 |
|---|---|---|---|
| 流量切回 | 蓝绿/灰度发布 | 将流量切回旧版本 | 秒级 |
| 镜像回滚 | 滚动发布 | 重新部署上一版本镜像 | 分钟级 |
| 配置回滚 | 配置变更 | 恢复上一版本配置 | 秒级 |
| 数据回滚 | 数据变更 | 执行回滚 SQL / 恢复备份 | 分钟~小时级 |
[Requirement] 发布前必须在发布单中明确回滚步骤,运维人员可独立执行。
发布单模板:
发布版本:v2.3.1发布人:张三发布时间:2024-01-15 14:00变更内容:新增订单导出功能回滚步骤: 1. K8s 回滚 Deployment:kubectl rollout undo deployment/user-service 2. 验证旧版本健康:curl http://user-service/health 3. 确认核心接口正常回滚耗时:约 3 分钟[Standard] 核心服务配置自动回滚策略,当监控指标异常时自动触发回滚。
# K8s 滚动发布配置
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
minReadySeconds: 30 # 新 Pod 就绪后至少等 30 秒
progressDeadlineSeconds: 300 # 5 分钟内未完成则视为失败- ❌ 发布后发现问题,先尝试修复再决定是否回滚,导致故障扩大。
- ❌ 没有回滚预案,出问题时临时想方案。
- ❌ 回滚依赖数据库结构变更,无法快速回滚。
[Requirement] 所有服务必须实现健康检查端点(/health),部署平台通过健康检查判断新实例是否就绪。
# FastAPI 健康检查示例
@app.get("/health")
async def health():
# 检查数据库、缓存等依赖
db_ok = await check_db()
redis_ok = await check_redis()
if db_ok and redis_ok:
return {"status": "ok"}
raise HTTPException(status_code=503, detail="unhealthy")[Requirement] 服务必须支持优雅停机:收到终止信号后,停止接收新请求,处理完在途请求后再退出。
# FastAPI 优雅停机
import signal
import asyncio
@app.on_event("shutdown")
async def shutdown():
# 等待在途请求完成(最长 30 秒)
await asyncio.sleep(30)
# 关闭资源
await db.close()[Standard] 优雅停机等待时间不超过 30 秒,超时后强制终止。
[Standard] 滚动部署时,每次只更新部分实例,确保服务始终可用。
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
spec:
replicas: 10
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 2 # 最多多出 2 个 Pod
maxUnavailable: 0 # 不允许不可用 Pod(保证零停机)[Standard] 部署前从负载均衡摘除旧实例,等待在途请求完成后再销毁。
1. 启动新版本 Pod2. 等待健康检查通过3. 新版本 Pod 加入负载均衡4. 旧实例标记为不可用,停止接收新请求5. 等待旧实例在途请求处理完成(≤30s)6. 销毁旧实例7. 重复直到所有实例更新完成[Caution] 数据库结构变更必须向后兼容,确保新旧版本代码可同时运行。
| 变更类型 | 兼容做法 | 不兼容做法 |
|---|---|---|
| 加字段 | 允许 NULL 或有默认值 | 加 NOT NULL 无默认值字段 |
| 删字段 | 先发布不使用该字段的代码,再删字段 | 直接删字段 |
| 改字段名 | 加新字段,双写,再删旧字段 | 直接 rename |
| 改字段类型 | 加新字段,迁移数据,再删旧字段 | 直接 alter |
[Requirement] 生产环境发布必须经过审批,流程如下:
提交发布单 → 技术负责人审批 → 运维审批 → 执行发布[Requirement] 发布单必须包含以下信息:
| 字段 | 说明 |
|---|---|
| 版本号 | 语义化版本号 |
| 变更内容 | 简要描述本次变更 |
| 变更范围 | 影响的服务、模块 |
| 风险评估 | 风险等级(低/中/高) |
| 发布时间 | 计划发布时间 |
| 回滚方案 | 详细回滚步骤 |
| 验证方案 | 发布后如何验证 |
| 变更类型 | 审批人 |
|---|---|
| 前端静态资源 | 前端负责人 |
| 后端服务(低风险) | 后端负责人 |
| 后端服务(高风险) | 后端负责人 + 运维负责人 |
| 数据库结构变更 | DBA + 后端负责人 |
| 基础设施变更 | 运维负责人 |
| 紧急热修复 | 值班负责人(事后补审批) |
[Requirement] 发布完成后,必须执行以下验证:
- 健康检查:所有实例
/health返回 200 - 冒烟测试:核心接口(登录、下单、支付)正常
- 监控指标:错误率、响应时间、资源使用率在正常范围
- 业务指标:核心业务指标无异常波动
[Standard] 发布后持续观察 30 分钟,无异常视为发布成功。
[Requirement] 每次发布必须记录发布日志,包括:发布人、发布时间、版本、变更内容、是否成功、回滚情况。保留至少 1 年。
- ❌ 发布单只有版本号,没有变更内容和回滚方案。
- ❌ 发布后不做验证,直接离开。
- ❌ 紧急热修复不走审批流程,事后也不补记录。
- ❌ 周五下午发布,出问题无人处理。