持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
背景:
用户打开页面的时候,需要根据页面的活动 id,渲染不同的迭代版本,例如活动 A 使用的代码是 v0.0.1(featureA),活动 B 使用的版本是 v0.0.2(featureB)
当然灰度策略不单单是活动 id,可能包括如下情况
- 按流量百分比
- 按地区
- 用户id
- 活动id
- 按ip
- 等等
目的
让产品应用逐步投放到市场,逐步发现问题,修改问题,适应市场
办法:
1. nginx + lua + apollo
推荐指数:⭐️⭐️⭐️⭐️
修改成本:⭐️⭐️⭐️
具体做法:用户请求 nginx,nginx 根据灰度策略判断当前用户需要渲染的版本后返回对应版本的 html, 判断版本的逻辑由 nginx 处理,灰度策略存放在某个数据库或者 apollo(比如白名单 ip,白名单 id,百分比值)
优势:
- 不改动前端业务代码,维护简单
劣势:
- 改造成本稍大,需要后端或者运维支援、需要使用 lua 语言,可能需要修改构建流程。
2. bff + apollo
推荐指数:⭐️⭐️⭐️
修改成本:⭐️⭐️⭐️⭐️
具体做法:类似第一种,只是把 nginx 换成了 node.js,适合有 bff 层,且 bff 承担渲染前端页面功能的项目
优势:
- 不改动前端业务代码,维护简单
劣势:
- 对于没有 bff 的项目或者有 bff 但不承担渲染任务的项目,改造成本大,需要引入 bff 层
3. 前端 ajax 请求后端接口。
推荐指数:⭐️
修改成本:⭐️⭐️⭐️⭐️⭐️
具体做法:用户请求 nginx,nginx 返回 html ,前端渲染 html, 执行 script 写好的 ajax 脚本,请求后端接口,拿到灰度的版本号,最后前端动态加载不同版本的入口 main.js。在这里灰度策略、灰度版本判断逻辑都放到了后端
优势:无
劣势:
-
改造成本比 2 还大,前端和后端都要改动
-
前端同步 ajax 会延迟页面加载,导致白屏,用户有感知,可能会有重定向。
4.前端业务代码逻辑判断
推荐指数:⭐️
修改成本:⭐️⭐️⭐️⭐️
具体做法:前端在代码里面 if else 判断,例如 A用户使用 A 组件,B 用户使用 B 组件
优势:
- 纯前端
劣势:
- 不适合项目级别控制的 A/B test,只适用于组件级别
- 代码冗余,可能有多版本,多个 if 判断 ,维护麻烦
5. 前端自己做资源的入口判断
推荐指数:⭐️⭐️⭐️⭐️
修改成本:⭐️
具体做法:用户请求 nginx,nginx 返回 html ,前端渲染 html, 执行 script 脚本,前端判断灰度的版本号,最后动态加载不同版本的入口 main.js。在这里灰度策略、灰度版本判断逻辑都放在前端 html 内的 script 脚本处理。
优势:
- 无需后端运维参与改造。
- 项目级别的灰度,不修改具体的业务代码
劣势:
需要灰度的时候,需要前端修改,增加前端工作量
看了上面几种情况,再总结一下,灰度发布的本质问题其实就 3 个
1. 打包的资源怎么处理,即怎么区分 featureA 的资源还是 featureB 的资源
通常我们打包的时候,只会放到这3个地方,怎么记录版本号呢?
- 上传到 cdn
可以通过资源地址的 hash 值判断
- 放到云服务器
需要每次打包出来的目录名不一致,然后根据资源目录名称,本质也是地址 hash 不同
- docker 镜像
通过镜像的版本号来判断
2. 灰度策略放在哪里
- 放到后端业务的数据库
- apollo
- 前端
3. 灰度版本的判断逻辑放在哪
- 可以放到 nginx
- 可以放到BFF(Node.js)
- 可以放到前端
但是这三个问题一结合,就会出现很多的灰度方案,结合自身项目选型的难度就会增大,可能还会涉及到 Docker ,多套服务器环境的情况,例如,使用灰度的时候,是灰度到另一套环境呢,还是只是前端资源的灰度。希望这篇文章能给大家带来一点启发。