前端知库

前端怎样做灰度发布和金丝雀发布?出问题怎样回滚?

金丝雀发布先让一小部分用户访问新版本,对比新旧版本的错误率和关键指标,没有退化再逐步放大比例。前端要让同一用户稳定命中同一版本,新旧两版的静态资源同时可用,接口对两版都兼容。回滚就是把流量切回旧版本,新版资源要保留到旧页面不再请求它们。

参考答案

简答

  • 金丝雀发布(也叫分阶段发布、增量发布)先把新版本开放给少量用户,观察指标没有退化后再逐步扩大,直到全部用户使用新版本。
  • 分流可以按随机比例、内部员工、地区或用户特征。前端分流要保持粘性,同一用户在一次会话内不能在新旧版本之间来回切换。
  • 新旧版本会同时在线,所以两版的 HTML 引用的静态资源都要能访问,后端接口和数据格式要同时兼容两版。
  • 判断标准要提前定好:对比金丝雀组和对照组的错误率、接口失败率、性能指标和关键业务转化,出现明显退化就停止放量。
  • 回滚就是把流量切回旧版本。已经打开新页面的用户还会继续请求新版资源,所以新版资源不能在切流时立刻删除。

分流放在哪一层

方式做法注意点
入口分流CDN、网关或边缘函数按 Cookie 或比例返回不同版本的 index.html入口 HTML 不能被长时间缓存,否则切流不生效
功能开关同一份构建,运行时按开关决定是否启用新功能新旧代码同时打包,开关清理不及时会积累分支

入口分流适合整站升级,例如更换框架或构建配置;功能开关适合单个功能的灰度,切换不需要重新发布。开关的稳定分桶和清理见《前端功能开关和灰度发布应该怎样设计?》。

新旧版本共存

带内容哈希的资源文件名(例如 app.3f2a1c.js)让两版资源互不覆盖。发布时把新资源追加到托管目录,而不是先清空再上传。

旧版本的页面在用户浏览器里可能停留很久,它按需加载的分片仍指向旧文件名。删除旧资源前要等足够长的时间,或者在加载分片失败时提示用户刷新。资源路径和缓存的检查方式见《静态托管发布时为什么要检查资源路径和缓存?》。

接口方面,先上线同时兼容新旧格式的后端,再灰度前端,全部切换后再移除旧格式支持。顺序反过来,旧版前端会在灰度期间出错。

观察指标与放量

  • 每个阶段(例如 1%、10%、50%、100%)停留一段时间,让指标有足够样本。
  • 监控和错误上报要带上版本号,才能把金丝雀组和对照组分开比较。
  • 金丝雀用于发现退化,按分钟到小时判断;A/B 测试用于验证产品假设,需要更长时间,两者不要混在一起。

回滚

入口分流时,把新版本的比例调回 0 即可,不需要重新构建。功能开关灰度时关闭开关。回滚之后仍要确认入口、资源和关键交互正常,完整流程见《静态网站发布失败时怎样安全回滚?》。

常见追问

  • 纯静态托管没有网关能灰度吗?托管平台不支持按请求分流时,只能在运行时用功能开关,或者发布到不同地址让部分用户访问。
  • 为什么用户刷新后版本变了?分流没有粘性,或者入口 HTML 被缓存。要用 Cookie 等标识固定分组,并让入口文件短缓存。
  • 数据库迁移怎么办?迁移要做到新旧代码都能运行,灰度阶段不能做只有新版能读的改动。