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

1. 灰度发布和A/B测试简介

灰度发布

将某个功能灰度发布(逐渐放量)给特定线上人群,避免新功能全量上线带来的风险。

上面的图可以通过两个方面来理解

  1. 蓝色实线和蓝色虚线访问Nginx服务器,nginx通过负载均衡将流量分摊到后端服务器。
  2. 黄色的线是应用了灰度的流量(配置Nginx规则)可以将特定流量分发到特定的机房,以达到对特定用户应用产品新功能;

举个简单的例子:将http请求cookie中含有test=1字段的请求都转发到灰度代码的机房;

上面通过通过配置特定Nginx规则的方法来达到产品灰度的方法虽然可以满足一定业务量的需求,但是他也有很多的缺点

  1. 不灵活,每次上线新业务代码需要做灰度都要重新更新nginx规则,造成开发和运维负担;
  2. 上线的代码要做机房区分,不能够将代码全量。本地的Git代码也要区分开发分支和测试分支,线上分支等若干分支,管理起开麻烦;
  3. 不能满足业务量大或者业务需要频繁迭代,需要频繁做测试的业务;

那么有没有更好的方法来做灰度发布呢?当然是有的,A/B测试就能够弥补上面通过Nginx规则来做灰度的缺点。

A/B测试

将线上一部分真实人群流量随机拆分成多个组,对每个分组的人群应用不同策略或功能,通过计算每组人群的业务指标(转化率、成交率等)来衡量策略或功能的实际效果。

我们通过下面的这张图简单的了解下A/B测试的原理:

由上图我们可以知道A/B和传统的灰度方法的区别:

传统的灰度是通过Nginx分发流量到服务器,A/B测试是通过业务代码区分流量访问不同的代码块。

那么A/B测试的优缺点是什么呢?

优点:

  1. 随着业务的变化不用频繁的变化Nginx规则,不用分机房上线业务代码,本地git分支不用为了做灰度而建专门的分支;
  2. 流量区分是业务代码做的。所以上线代码的时候可以全量上线到所有机房;

缺点:

  1. 因为流量区分是业务代码做的。所以在代码中会存在很多的if...else分支语句。但是这样还好,因为根据SDK的规范来书写代码,还是很好管理的。

2. 基于A/B测试的前端灰度怎么做

前端跟后端很大的区别就是直接面对用户,就算很简单的修改一次按钮的颜色就需要一次上线。这种操作对用户是可感知的。

现代前端有个特点就是脱离了后端模板引擎的渲染,大多数是使用React、Vue这种MVVM框架的前端(浏览器)渲染。这种情况下后端其实仅仅是给用户提供一个空的html文件(工作中经常称作为壳)。大多数业务代码开发完以后都是作为静态文件上线到服务器,经过用户访问后缓存到CDN节点上的。而且这个过程大多数是增量上线的。

其实我们每次上线完之后服务器上缓存的html文件就包含不同的版本信息。如果我们把这些版本信息管理起来,并且通过特定的手段(对用户请求应用A/B测试)就可以完成前端不同版本的灰度发布。

使用Nodejs灵活控制前端发布

我们可以观察下Webpack或者是其它打包工具打包后的html文件。每次外联的静态文件都包含不同的hash戳。这些外链的文件又都是增量缓存到服务其上的。

index.html (我们页面的“壳”)
一些 xxx.js文件 (渲染页面+页面的业务逻辑)
xxx.css 文件 (控制页面显示样式)

大概就是下面的这个样子

基于以上的特点,我们能不能尽量减少对业务代码侵入,而可以覆盖业务改动较大的需求进行灰度或者是A/B测试呢?

看下下面的这个这个请求的图:

每次我们打包编译完之后,就将相关的css文件和js文件信息保存到本地的一个json文件中。这些信息的key可以是我们的git的tag信息(主要来描述本次发版信息包含的功能等)。

基本上json文件包含的信息如下:

const version = {// 可以描述本次的上线内容/ 或者是git tag'tag1': {'css': 'xxxxxxx.css','app': 'app_xxx.js','ventor': 'ver_xxx.js'}
}

这里仅仅是一个简单的demo示例,可以使用Nodejs写文件的特性直接将文件版本号写入到index.html返回给前端浏览器

Nodejs服务的特点是每次更新完代码需要重启之后才能生效。每次上完线重启服务就会先检查本地代码根目录下的这个json文件。看下这个其中包含的tag是否在DB中存储,如果有存储就不做操作,如果没有就将它存储DB做持久化。

上面图上面的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打包工具的时候将server目录下的给排除掉。放置不必要的编译和产出,增加打包速度。

  • 线上url的约定

当使用了新的服务的时候为了防止跟旧业务的冲突肯定需要使用新的url。这个时候就需要做一些约定。目前我们是这么约定的

// 域名/产品线/模块/
http://wwww.aaa.com/driver/bus/index.html
// 域名/产品线/模块/静态文件目录
http://wwww.aaa.com/driver/bus/static/js/index.js
http://wwww.aaa.com/driver/bus/static/css/index.html

兼容老业务需要做的工作

前面提到这次业务升级我们使用了新的url,但是为了保证业务的稳定性我们不是一次性将所有的流量都切到新服务上去的。我们也是通过批量的切的,所以会存在线上用户有的地区访问新服务有地区访问旧服务。那么有一天会有全部切换的一天,但是还是会有一些用户访问到旧链接,这个时候可以通过配置Nginx 的`rewrite来讲旧链接都转成新的链接。

  1. 升级后的业务怎么访问新的连接
  2. 已经请求相关的配置

避免不必要的请求

前端路由可以分为两种方式,hash和path切换。因为对于前端渲染页面来说,当第一次请求完成后,其实所有的页面都已经下载到了本地(页面异步加载除外)。在我们通过path切换页面的时候,每次都会向服务端发送请求,其实这些请求是不需要到达Nodejs服务的。我们可以通过Nginx配置将这些无用的流量抵挡在Nginx这一层,减少服务器的压力。

如果是使用hash的方式则不存在这样的问题,但是会有另外的问题就是对搜索引擎不友好。当然前端路由切换还是应该根据自己的业务做取舍。

4. 前端业务拓展

当我们应用了Nodejs服务之后,可以拓展的技术点有哪些,一下简单列举一些:

  1. 服务端渲染:提高首屏渲染时间,提升用户体验。
  2. 前端接口校验:增加前端访问后端接口,后端接口返回数据的安全性。
  3. 前后端分离,前端工程师的灵活性更加的高。

5. 技术升级带来的收益

  1. 前端上线可以实现小流量、灰度、发布,可以对线上流量做A/B测试,减少线上问题;
  2. 可以定制化对部分用户推动新功能;
  3. 加快首屏的渲染时间,提升用户体验;
  4. 多机房部署前端代码,降低前端服务不可用的风险;
  5. 团队成员技术能力的提升;

6. 最后

当然这种方案也不仅仅是可以使用Nodejs来做,也可以使用其它语言。因为我们公司已经有基于A/B测试的Nodejs-SDK。我这我就不具体介绍原理了。原理可以参考百度百科。如果有问题需要一起讨论可以留言或者是邮箱联系我:hpuhouzhiqiang@gmail.com

基于Nodejs的前端灰度发布方案_20190228相关推荐

  1. 一种前端灰度发布方案

    本文介绍一种前端灰度发布方案,主要解决的是传统的灰度发布只能以机器维度进行分组的问题.提供一种用户维度分组的灰度发布机制. 传统灰度发布,因为是以机器分组,所以要求服务是无状态的.所谓无状态就是对请求 ...

  2. git灰度发布版本_一种前端灰度发布方案

    (给前端大学加星标,提升前端技能.)作者:吕大豹 https://www.cnblogs.com/lvdabao/p/11920919.html 本文介绍一种前端灰度发布方案,主要解决的是传统的灰度发 ...

  3. 基于 GateWay 和 Nacos 实现微服务架构灰度发布方案

    一.灰度发布 灰度发布(又名金丝雀发布)是指在黑与白之间,能够平滑过渡的一种发布方式.在其上可以进行A/B testing,即让一部分用户继续用产品特性A,一部分用户开始用产品特性B,如果用户对B没有 ...

  4. Web服务不停机更新和灰度发布方案

    文章目录 Web服务不停机更新和灰度发布方案 当前情况 方案一 负载均衡: 问题: 方案二 灰度发布: 用IF指令实现 根据来源ip做判断 根据cookie做判断 使用lua写脚本实现 使用nginx ...

  5. 基于spring cloud 的灰度发布实践_【收藏】基于spring cloud灰度发版方案

    简介 敏捷开发迭代周期短发布快,每周都可能面临版本发版上线,为最大可能的降低对用户的影响提高服务可用率,大部分团队都需要等到半夜做发布和支持.本文就如何基于spring cloud体系做灰度发版改造提 ...

  6. 11.落地:微服务架构灰度发布方案

    前置知识 1.nacos 服务注册与发现 2.本地负载均衡器算法 3.gateway 网关 4.ThreadLocal 1.什么是灰度发布? 2.什么是灰度策略? 3.灰度发布落地方案有哪些 4.灰度 ...

  7. 基于apollo实现配置灰度发布

    前言 在上一篇,通过dubbo的版本号控制,我们实现了一个服务的简单的灰度发布过程,在真实的项目环境中,灰度发布的应用场景是很多的,服务接口存在灰度的需求,本篇再介绍另一种比较常见的灰度需求场景,即配 ...

  8. 关于App灰度发布方案

    一. 灰度发布定义 灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围, ...

  9. dubbo灰度发布方案

    背景 目前我公司自己搭了一套发布系统,底层使用的是docker的swarm,实现了"灰度发布"功能.当开启发布灰度发布的时候,会独立启动一个容器,只允许指定百分比的流量进入到灰度容 ...

最新文章

  1. 牛X!Eclipse 开始支持 Java 14~
  2. notepad 如何运行php,notepad怎么运行c
  3. python计算颜色占比_用 Python 对图片主体轮廓进行提取、颜色标记、并计算区域面积...
  4. LEADTOOLS Multimedia SDK更新:改进RTSP和H.265/H.264的硬件加速
  5. 嵌入式成长轨迹52 【Zigbee项目】【CC2430基础实验】【在PC用串口收数并发数】...
  6. C++之关键字:override
  7. svg的viewport和viewbox
  8. (并查集) Wireless Network --POJ --2236
  9. php基础教程 第五章,php基础教程——5数据库总结_PHP教程
  10. tablelayout
  11. 禁止双击、拖动listctrl列头
  12. Latex中导入VISIO图片
  13. cad2019菜单栏怎么调出来_AutoCAD2019工具栏怎么调出来 工具栏没了找不到解决方法...
  14. excel英文大小写转换
  15. 如何设置代理服务器?
  16. innobackupex 简单使用笔记
  17. AndroidQ SystemUI之插件化机制Plugin
  18. 利用百度AI开放平台 实现 图片中的文字识别
  19. vue全局组件自动注册
  20. python imageio安装_imageio.ffmpeg.download()需要安装不同的imageio,并且imageio不会安装其他版本...

热门文章

  1. Android ViewGroup
  2. java继承的范例_Java范例中的继承
  3. 让我们在Ubuntu 18.04上加密SSL证书来保护Nginx
  4. c ++创建二维数组_C ++中的二维数组
  5. 深入了解VPP关键技术有哪些?
  6. svn添加提交备注限制和自动发布web项目
  7. 酷客多小程序携手Richly network Pte Led正式进军新加坡市场
  8. react-native开发安卓app相关使用总结
  9. 小程序web开发框架-weweb介绍 1
  10. Android 单元测试cmd 命令集