前言

很多线上故障都发生在发布之后。面试官常问:上线后出问题怎么办?怎么判断是不是新版本导致的?什么时候回滚?配置变更、数据库变更和缓存兼容怎么排查?

典型现象

  • 发布后错误率升高。
  • 只有灰度用户报错。
  • 部分实例异常,部分实例正常。
  • 新老版本同时运行时数据异常。
  • 配置刷新后接口行为变化。
  • 数据库字段变更导致兼容问题。

排查流程

flowchart TD
    A[发布后告警] --> B[确认影响范围]
    B --> C[对比发布时间]
    C --> D[查看灰度批次]
    D --> E{是否新版本相关}
    E -->|是| F[回滚或关闭开关]
    E -->|否| G[继续排查依赖和流量]
    F --> H[数据修复和补偿]
    G --> H
    H --> I[复盘和治理]

第一时间看什么

  • 发布批次。
  • 版本号。
  • 灰度范围。
  • 错误率和 P99。
  • 影响接口。
  • 影响用户。
  • 最近配置变更。
  • 数据库变更。

如果错误率和发布时间高度吻合,要优先按发布故障处理。

快速止血手段

手段 适用场景 注意点
关闭开关 新功能可降级 要提前设计开关
回滚版本 代码问题明确 注意 DB 是否兼容
缩小灰度 只影响灰度用户 保留现场日志
限流 流量触发问题 防止核心链路雪崩
降级 非核心依赖异常 返回可接受兜底结果
暂停任务 批处理导致故障 防止继续污染数据

生产处理原则是先止血,再定位。不要为了找根因让故障持续扩大。

常见发布故障

配置变更错误

常见问题:

  • 配置中心推错环境。
  • 灰度规则写错。
  • 开关默认值不兼容。
  • 配置刷新后未校验。
  • 配置项类型错误。

治理方式:

  • 配置变更审批。
  • 配置版本管理。
  • 灰度发布配置。
  • 配置回滚。
  • 配置校验和默认值保护。

数据库变更不兼容

常见问题:

  • 先删字段再发代码。
  • 字段改名导致老版本报错。
  • 新增非空字段没有默认值。
  • 索引缺失导致发布后慢查询。
  • DDL 锁表影响线上请求。

推荐顺序:

  1. 先加兼容字段。
  2. 发布兼容新老字段的代码。
  3. 数据迁移。
  4. 切换读写。
  5. 确认无老版本后删除旧字段。

缓存结构不兼容

新版本改了缓存 value 结构,老版本读不了,或者老缓存没有新字段。

处理方式:

  • 缓存 key 增加版本号。
  • 反序列化兼容旧字段。
  • 发布前预热新缓存。
  • 删除缓存要分批,避免雪崩。

接口兼容问题

前后端、服务间接口变更如果没有兼容,会导致部分调用失败。

治理方式:

  • 新增字段不影响老调用方。
  • 删除字段前确认无调用。
  • 枚举值变更要兼容。
  • 接口版本化。
  • 契约测试。

回滚要注意什么

回滚不是简单部署旧包。要确认:

  • 数据库结构是否还兼容旧版本。
  • 配置是否需要回滚。
  • 缓存结构是否兼容。
  • MQ 消息格式是否兼容。
  • 是否已经产生新版本数据。
  • 是否需要补偿任务。

如果新版本已经写入了旧版本不认识的数据,直接回滚可能造成二次故障。

发布前预防

  • 灰度发布。
  • 开关控制。
  • 自动化回归。
  • 数据库变更评审。
  • 核心链路压测。
  • 监控和告警预案。
  • 回滚脚本演练。

高频面试题

上线后接口 500 怎么办?

先看影响范围、版本批次、错误日志和发布时间。如果与发布强相关,先缩小灰度、关闭开关或回滚,再保留日志定位根因。

什么情况下不能直接回滚?

如果数据库结构、缓存格式、MQ 消息格式或已写入数据与旧版本不兼容,直接回滚可能产生更大问题。要先评估兼容性和数据修复方案。

灰度发布的价值是什么?

灰度可以把影响范围控制在小部分用户或实例,通过监控验证新版本稳定性,发现问题时快速停止扩大影响。

总结

发布后故障排查强调速度和边界。面试时要讲清楚灰度、开关、回滚、兼容、数据修复和复盘治理,而不是只说“看日志”。