当前位置: 首页 > 后端技术 > Node.js

基于Nodejs的前端灰度发布方案_20190228

时间:2023-04-04 00:09:22 Node.js

Nodejs的前端灰度发布方案1.介绍灰度发布和A/BTesting人群,规避新功能全面上线带来的风险。上图可以从两个方面来理解:蓝色实线和蓝色虚线访问的是Nginx服务器,nginx通过负载均衡将流量分发到后端服务器。黄线是灰度流量的应用(配置Nginx规则),可以将特定的流量分配到特定的机房,从而将新的产品功能应用到特定的用户;举一个简单的例子:设置http请求cookie中包含test=1字段的请求转发到灰度代码的机房;上述通过配置特定Nginx规则实现产品灰度的方法可以满足一定业务量的需求,但是也有很多缺点:不够灵活,每次上线新业务代码都需要灰度,nginx规则必须是再次更新,造成开发和运维负担;上线代码需要机房区分,无法加载完整代码。本地Git代码还需要区分开发分支和测试分支、线上分支和其他分支,管理起来会比较麻烦;不能满足业务量大或业务迭代频繁、测试频繁的业务;有没有更好的办法?灰度发布怎么样?当然有,A/B测试可以弥补以上使用Nginx规则做灰度的不足。A/B测试将线上真实人群流量的一部分随机拆分成多个组,对每组人应用不同的策略或功能,通过计算用户的业务指标(转化率、成交率等)来衡量策略。每个人群或功能的实际效果。我们通过下图简单了解一下A/B测试的原理:从上图可以知道A/B与传统灰度法的区别:传统灰度法通过Nginx将流量分发到服务器,A/BB测试是通过业务代码来区分访问不同代码块的流量。那么A/B测试的优缺点是什么?优点:随着业务的变化,无需频繁更改Nginx规则,业务代码无需在扩展机房上线。本地git分支不需要为灰度建立专门的分支;流量划分由业务代码完成。因此,代码启动时,可以全面启动到所有机房;缺点:因为流量划分是由业务代码完成的。所以代码中会有很多if...else分支语句。不过这样也没关系,因为按照SDK规范写代码还是好管理的。2、如何做基于A/B测试的前端灰度。前端和后端最大的区别就是直接面对用户。哪怕是很简单的改变一个按钮的颜色,也需要上线一次。该操作是用户可感知的。现代前端的一个特点是与后端模板引擎的渲染分离。大多使用React、Vue等MVVM框架的前端(浏览器)渲染。在这种情况下,后端实际上只是向用户提供一个空的html文件(工作中通常称为shell)。大部分业务代码开发完成后,以静态文件的形式上传到服务器,用户访问后缓存在CDN节点上。而且这个过程的大部分是增量启动的。事实上,我们每次上网时,缓存在服务器上的html文件都包含不同的版本信息。如果我们管理好这些版本信息,通过特定的手段(对用户请求进行A/B测试),就可以完成前端不同版本的灰度发布。使用Nodejs灵活控制前端发布,我们可以观察Webpack或者其他打包工具打包后的html文件。每个外部静态文件都包含不同的哈希戳。这些外部链接的文件都是增量缓存在服务上的。index.html(我们页面的“外壳”)一些xxx.js文件(渲染页面+页面的业务逻辑)xxx.css文件(控制页面显示样式)大概就是下面这些。基于以上特点,我们能不能尽力而为?减少业务代码的侵入,能否覆盖大业务变更对灰度或A/B测试的需求?看下面这个请求的图片:我们每次打包编译的时候,都会把相关的css文件和js文件信息保存到本地的json文件中。这些信息的key可以是我们的gittag信息(主要是描述本次发布信息包含的功能等)。基本上json文件包含的信息如下:constversion={//可以描述本次上线的内容/或者gittag'tag1':{'css':'xxxxxxx.css','app':'app_xxx.js','ventor':'ver_xxx.js'}}这只是一个简单的demo例子,可以利用Nodejs写文件的特性,直接将文件版本号写入index.html返回给前端浏览器。Nodejs服务的特点是每次更新代码都需要重启才能生效。每次上线后重启服务,都会先检查本地代码根目录下的json文件。检查其中包含的标签是否存储在数据库中。如果已存储,则不会对其进行操作。如果没有,它将存储在数据库中以进行持久化。上面的Apollo是用于配置这些用户以访问新功能的平台。在Nodejs端,每收到一个用户请求,就会判断用户的信息是否满足相关条件,然后从DB中读取相关的静态文件信息,渲染到index.html中。简单总结:先存储每次打包的静态文件信息,然后在请求到达Nodejs时判断用户是否满足相关条件。如果是,则读取DB,返回相关静态文件信息给Nodejs,Nodejs渲染静态页面后,返回给用户,达到灰度化的目的。3.其他细节问题在使用Nodejs之前,我们的页面都是直接部署在服务器上的。这次用了Nodejs之后,还会有很多其他的问题要做,比如Nodejs服务的监控,多机房的部署等等,大部分公司应该都有相关的运维工程师来做这些。这里我简单介绍一下其他一些内容规范的确定。这里的规范包括本地开发时项目目录的规范和在线用户访问url的规范。开发目录规范的最新Nodejs版本是作者写这篇文章时的11.10版本,最新的LTS版本是10.15.1版本。建议使用Nodejs的同学将Node升级到8.0以上版本,因为8.0版本是官方版本,原生支持async...await语句。.├──client//放置客户端代码├──index.html├──index.js├──node_modules├──output├──package-lock.json├──package.json├──server//放置服务端Nodejs代码├──test.sh在编写webpack打包工具时需要注意排除服务端目录。放置不必要的编译输出,提高打包速度。在线url协议使用新服务时,需要使用新的url,以防止与旧业务发生冲突。这个时候,需要达成一些协议。目前我们约定了这个//域名/产品线/模块/http://wwww.aaa.com/driver/bus/index.html//域名/产品线/模块/静态文件目录http://www.aaa.com/driver/bus/static/js/index.jshttp://wwww.aaa.com/driver/bus/static/css/index.html需要做旧业务的兼容新的url是用的,但是为了保证业务的稳定性,我们不会一次性把所有流量都切换到新服务上。我们也是分批切分的,所以会有在线用户在一些地区访问新服务,在其他地区访问旧服务。然后总有一天一切都会被切换,但一些用户仍然会访问旧链接。这时候可以通过配置Nginx的rewrite将旧链接转换为新链接。升级业务请求相关配置后如何访问新连接,避免不必要的请求。前端路由可以分为哈希和路径切换两种方式。因为对于前端渲染页面来说,当第一次请求完成后,其实所有的页面都已经下载到本地了(异步页面加载除外)。当我们通过路径切换页面时,每次都会向服务器发送请求。其实这些请求是不需要到达Nodejs服务的。我们可以通过Nginx配置在Nginx层屏蔽这些无用的流量,减轻服务器的压力。如果是使用hash的方式,就没有这个问题,但是会有另外一个问题,就是对搜索引擎不友好。当然,前端路由切换还是要根据自己的业务。4、前端业务扩展我们应用了Nodejs服务后,可以扩展的技术点有哪些,简单罗列几点:服务端渲染:提高首屏渲染时间,提升用户体验。前端接口校验:增加前端访问后端接口和后端接口返回数据的安全性。前后端分离,前端工程师的灵活性更高。5、技术升级带来的收益前端可以做到小流量、灰度、发布,可以对线上流量做A/B测试,减少线上问题;可定制,为部分用户推广新功能;加快首屏渲染时间,提升用户体验;前端代码部署在多个机房,降低前端服务不可用的风险;提高团队成员的技术能力;6.最后,当然这个方案不仅仅可以用Nodejs来完成,其他语言也可以。因为我们公司已经有了基于A/B测试的Nodejs-SDK。原理我就不详细介绍了。原理可以参考百度百科。如果有什么问题需要一起讨论,可以留言或者邮件联系我:hpuhouzhiqiang@gmail.com