什么是灰度环境?我们先看看百度上对于灰度发布的定义,如下:
从产品功能角度来说,新上线某个功能,可以让一部分用户先体验,或者对某个存量功能做了改造,但是先让一部分用户进行试用,等功能稳定,并且反馈较好的时候,再到正式环境发布。
从开发的角度来说,我理解灰度环境其实是准生产环境,也就是说数据库、中间件这些应该是和生产环境公用的。
这里要区分测试环境和灰度环境,主要区别就是灰度环境其实也是准生产环境,也就是说在灰度环境上操作产生的数据也会同步在生产环境有体现。
项目基本信息:后端使用SpringBoot、dubbo,前端使用vue。前后端分离的开发方式,静态资源直接放在Nginx的html下,通过Nginx代理出去访问。
项目包括的主要工程有:
(1)登陆及门户框架工程
主要是登陆校验以及登陆成功后的主框架。 主框架左侧是菜单区域,这个前端工程不区分灰度和生产,因为功能比较独立和稳定,菜单区域的菜单根据用户类型不同,url有区别。 菜单表中关于url配置有有两个字段,生产url和灰度url。 灰度用户登陆成功之后查询的是灰度url。所以对于门户工程这里,点击菜单的时候,访问的url一定待/grey,也就是到灰度环境。
(2)所有业务功能对应的前端工程
这是所有业务功能的前端工程。
(3)网关应用
(4)业务后端应用
实际业务开发的后端应用。
项目不同,需求肯定是有差异的,我今天要讲的灰度方案不一定适用于所有项目,仅供参考。关于这套灰度方案有以下几点要求:
(1)用户需要区分灰度用户和生产用户,灰度用户访问灰度环境,生产用户访问生产
(2)灰度环境和生产环境公用一套Nginx集群,有相同的系统入口
(3)灰度发布的时候,只发布灰度环境,生产环境对应的应用版本不变。
(4)灰度环境和生产使用相同的数据层。
可能会有人说,如果会灰度和生产都用同一套数据库,如果新上线的功能需要对存量表进行修改,生产的应用不升级就会报错,怎么办?这种情况其实是有可能存在,但是一般情况下,对于有灰度环境的系统或者产品而言,一定是有实际的生产用户在用,这种场景下一定是会杜绝出现对现有表模型某个字段做修改的情况,因为影响范围比较大,毕竟,鱼和熊掌不可兼得嘛,所以我们也无需纠结这些细节。
下面我们来看一张部署及请求架构图:
实现这个灰度方案的主要关键点在于:
(1)通过在url请求中添加/grey来区分是否是灰度请求
(3)前端打包的时候,所有请求都使用相对路径,即使用浏览器当前默认域
(5)灰度发布的时候,只更新灰度Nginx下的前端静态资源,和灰度app。
请求通过F5进来之后,先到Nginx,Nginx根据是否有/grey,转到对应的网关,通过这条线其实就能区分开请求了。
两个nginx的配置是一模一样的,Nginx本身不区别灰度和生产,唯一的区别就是静态有区别。
upstream api-gateway {
sticky;
server 10.26.80.19:18083;
server 10.26.80.20:18083;
}
upstream api-gateway-grey {
sticky;
server 10.26.80.19:18084;
server 10.26.80.20:18084;
}
server{
listen 8013;
server_name 10.20.230.158;
location /grey/{
proxy_pass http://api-gateway-grey;
}
location / {
proxy_pass http://api-gateway;
}
}
从我个人的理解来说:
(1)我觉这算不上一种很好的灰度方案,理想的灰度方案应该是不区分所谓的灰度用户的,应该是松耦合灵活发布的。比如我们对功能A做了改造和升级,在灰度发布之后,某一小部分用户(随机或者灵活指定)就会发现这个功能和升级前不同了,但是其他用户看到的还是之前的功能。 这才是互联网产品的一个灰度发布效果。
(2)大部分企业级的系统其实没必要这么复杂,为了xx而xx,完全没必要,但是很多时候甲方的负责人可能是SB,态度就是:我不管,我就是要,你弄不了你想办法。初衷是怎么把这个系统吹的很高大上,而不是切合实际的解决一线的问题。