跳到主要内容

线上回滚策略

问题

新版本上线后发现问题,如何快速回滚?代码、SQL、配置分别怎么回滚?

答案

回滚决策流程

代码回滚

K8s 回滚
# 查看部署历史
kubectl rollout history deployment/order-service

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

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

# 查看回滚状态
kubectl rollout status deployment/order-service
Docker 回滚
# 重新指向上一个镜像
docker stop order-service
docker run -d --name order-service registry/order-service:v1.2.3 # 旧版本 tag

SQL 回滚

SQL 回滚最危险

数据变更一旦执行,回滚成本远高于代码回滚。关键原则:数据变更必须有回滚 SQL 且先备份。

DDL 回滚
-- 变更:添加列
ALTER TABLE orders ADD COLUMN remark VARCHAR(200);

-- 回滚 SQL(提前准备好)
ALTER TABLE orders DROP COLUMN remark;
DML 回滚
-- 变更前先备份
CREATE TABLE orders_backup_20240115 AS SELECT * FROM orders WHERE status = 1;

-- 执行变更
UPDATE orders SET status = 2 WHERE status = 1 AND create_time < '2024-01-01';

-- 如需回滚
UPDATE orders o
INNER JOIN orders_backup_20240115 b ON o.id = b.id
SET o.status = b.status;

数据变更规范

  1. 变更 SQL 和回滚 SQL 必须成对出现
  2. DML 必须先备份受影响的数据
  3. 大批量更新分批执行
  4. 生产环境变更需审批

配置回滚

Nacos / Apollo 配置回滚
Apollo 管理界面 → 选择版本 → 一键回滚

Nacos:
配置管理 → 历史版本 → 选择回滚版本 → 回滚

灰度发布与快速回滚

灰度策略:

  1. 新版本部署少量实例(10%)
  2. 观察错误率、RT、业务指标
  3. 正常 → 逐步扩大流量比例
  4. 异常 → 立即将灰度流量切回旧版本
K8s 金丝雀发布
# 新版本 Deployment(少量副本)
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service-canary
spec:
replicas: 1 # 只起 1 个副本测试

回滚 Checklist

步骤动作
1. 止血立即回滚代码/配置
2. 验证确认回滚后服务恢复正常
3. 通知告知相关方
4. 排查分析根因
5. 修复修复后重新灰度上线
6. 复盘完善流程避免再犯

常见面试问题

Q1: 上线出问题的第一反应是什么?

答案

先止血,后排查。第一时间回滚恢复服务,而不是在线上 debug。回滚后再慢慢排查根因。

Q2: 如何减少上线风险?

答案

  1. 灰度发布:小流量验证
  2. Feature Flag:代码合入但功能不开放,开关控制
  3. 向前兼容:新版本兼容旧数据格式
  4. 数据库先行:SQL 变更在代码上线前执行
  5. 可观测性:完善的监控和告警

Q3: 数据库变更如何做到可回滚?

答案

  • 添加字段:兼容旧代码,无需回滚
  • 删除字段:先停止使用 → 观察 → 再删除
  • 修改数据:备份 + 回滚 SQL
  • 大表 DDL:在线 DDL 工具(gh-ost / pt-osc)

相关链接