一个较大的前端项目在发布时,会采取灰度发布的模式,每一个新的feature版本,都不会全量推送给所有用户,而是会先部门灰度,再推送给部分用户使用验证,验证OK后再扩大推送用户面积,最后再全量发布。
什么是灰度发布
将某个功能灰度发布(逐渐放量)给特定线上人群,避免新功能全量上线带来的风险。
什么是灰度规则
灰度规则可以是用户等级、性别、地区、客户端等业务信息或者设备信息,比如灰度规则设定为广东地区的用户访问1.1版本,那么广东用户访问时就算命中了灰度规则,给他们转去1.1版本,其他地区的用户继续使用1.0版本。
常见的灰度发布方案
1、简单的nginx分流(推荐指数:⭐)
本身只依赖nginx来做分流还算不上灰度发布,但是可以有一些骚操作,可以实现类似灰度发布的一些操作,
1、两个版本使用两份代码,分别部署;
2、通过nginx加权轮询来控制访问百分比,客户端的cookie不存在标识的情况下;
3、使用前端在携带的cookie中存入sdk(一个随机不重复的标识(还是有可能重复));
4、二次访问的时候,nginx通过对cookie中唯一标识来返回对应版本。
优点:简单,不涉及后端操作
缺点:1、只能简单依赖nginx加权轮询来控制流量,全靠前端,无法结合业务做分流;
2、可控性差,在灰度版本出现问题的时候,只能通过修改nginx配置来让用户回退版本;
3、问题收集能力差,只能等待用户反馈;
4、在客户端cookie被清理掉后,用户需要重新添加sdk,并通过nginx重新加权轮询决定分配版本,有可能就会出现分配到与上一次分配不同的版本。
2、nginx + lua + redis(推荐指数:⭐⭐)
1.当用户请求到达前端代理服务nginx,内嵌的lua模块解析nginx配置文件中的lua脚本代码
2.lua变量获取到客户端的ip地址,去查询redis缓存内是否有该键值,如果有返回值执行灰度版本逻辑,否则执行当前生产环境版本。
3、服务端渲染分流(推荐指数:⭐⭐⭐)
1.前端打包好的两个版本的代码分别部署到服务器上(这里以单页面应用为例,多页面的话需要单独处理一些细节);
2.在后台管理添加版本(实际上就是让服务端读取单页面的index.html);
客户端访问服务器,服务端根据灰度规则set-cookie并存在redis储存,返回对应版本的index.html;
3.二次访问通过服务端时,如果存在cookie并且redis已经存在对应的版本信息,则直接返回,否则重新走灰度流程。
优点:灵活、可控性强,可结合业务体系做灰度放量规则,缺点:几乎是后端把事情全干了,对服务器压力比较大,需要做的优化多,多页面应用使用比较麻烦。
4、客户端注释判断(比较难维护)(不推荐)
客户端通过注释条件来编译,来做灰度规则,其实就是根据灰度规则对应在代码层面上做判断显示那些版本的功能,这种方案也有公司在使用,灰度功能一旦多了,非常难以维护。
5、nginx + 服务端 + redis + 前端sdk(推荐指数:⭐⭐⭐)
整体方案概述:
1.我们先把线上稳定版本称为stable版,本次发布的新功能版本称为beta版;
2.开发人员给stable和beta版本各自启动了nginx服务,在运维层启动了一层入口nginx服务,作为转发;
3.客户端通过域名访问项目,如果通过请求灰度规则,命中灰度规则后,并给客户端设置cookie作为标识,并将用户标识放进redis,将用户重定向到指定的版本;
4.灰度规则接口请求的时候,如果已经带有cookie则直接返回对应的版本,不存在cookie则去查找redis,redis中存在对应信息则直接返回,如果不存在则走灰度规则识别流程;
5.前端sdk功能:用于控制发起灰度规则请求的实际,回调操作和其他业务操作。
sdk的使用场景:
项目中需要在特定的时机触发灰度功能,比如,点击某个按钮,或者,进入某个页面,比如某些页面会弹出一个弹出框,告诉用户有内测版本,是否要体验,点击同意后,才跳转到灰度版本。
常见的灰度问题处理
如果上线后灰度版本出现严重的问题,需要紧急回退操作,我们可以:
1.直接后台关闭灰度功能;
2.清除redis中储存的用户灰度版本信息;
3.结束用户的登录会话(清除客户端的cookie);
如果我们需要用户进入某个指定的版本,可以:
1.后台修改redis信息;
2.结束用户的登录会话
指定项目中某个页面才启用灰度,可以:
1.在前端sdk处理相关逻辑,把相关的页面路径作为名单给前端识别(sdk最好动态引入,sdk放在cdn上)。