基于Nginx实现灰度在线系统的完整流程
软件开发一般不会有最终版本,而是从一个版本到另一个版本迭代。
新版本上线前会进行测试,但不保证上线时不会出现问题。
所以,新版本的代码一般都是通过公司内的灰度系统发布。
灰度系统可以将流量分成几部分,一部分使用新版本代码,另一部分使用旧版本代码。
并且灰度系统支持调整流量比例。例如,您可以将新版本代码流量设置为5%。如果没问题的话,设置为10%、50%,最后设置为全额的100%。
这可以最大限度地减少问题的影响。
不然一到就全款用完。如果网上出了问题,那将是一场大灾难。
而且灰度系统不仅仅用于这个目的。例如,如果产品不确定某个改动是否有效,就需要进行AB实验,即将流量分为两部分,一部分使用代码版本A,另一部分使用代码版本A代码版本B.版本代码。
灰度系统是如何实现的?
其实很多都是使用nginx实现的。
nginx 是一个反向代理服务。用户请求被发送并转发到特定的应用服务器。
该层也称为网关层。
它负责将请求转发到应用服务器,所以你可以控制这里的流量分配,流向版本A的流量和流向版本B的流量。
我们来实现如下:
首先,我们设置两个代码的版本。
在此创建nest项目:
npx nest new gray_test -p npm

运行nest服务:
npm run start

使用浏览器访问:
看到hello world,表示nest服务正在运行。
然后更改AppService:
修改端口:
然后npm run start:
浏览器访问:
现在我们有两个版本的嵌套代码。
下一个问题,如何使用nginx实现灰度,让部分请求走一个代码版本,部分请求走另一个版本?
我们先启动nginx服务。
Docker桌面正在寻找nginx镜像(这一步需要科学上网),点击运行:
将容器名称设置为gray1,并将端口从主机上的82映射到容器上的80
现在访问 http://localhost : 82 就可以看到 nginx 页面:
我们需要修改配置文件并复制它:
docker cp gray1:/etc/nginx/conf.d ~/nginx-config

然后编辑这个default.conf
添加此配置行:
location ^~ /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://192.168.1.6:3001;
}
添加此行 转发以 /api/ 开头的请求到服务 http://主机 IP:3001 的路由。
使用rewrite重写url,例如/api/xxx改为/xxx。
然后重新打开nginx容器:
容器名为gray2,端口83映射到容器中的80。
定义数据卷,并将本地~/nginx-config目录挂载到容器的/etc/nginx/conf.d目录中。
单击运行。
然后查看文件部分:
可以看到容器中的/etc/nginx/conf.d目录被挂载了。
点击查看:
这是本地文件。
我们尝试在本地更改它:
容器也以同样的方式更改。
如果你在容器中修改这个文件,本地也会被修改。
也就是说,挂载数据卷后,容器中的目录是本地目录,并且是本地目录的副本。
然后访问http://localhost:83/api/,看到:
nest服务访问成功。
现在我们不直接访问Nest服务,而是经过nginx反向代理层或者网关层。
自然,我们可以在这一层实现流控功能。
之前讲负载均衡的时候,配置如下:
默认情况下,请求会发送到轮询下面的服务器。
现在你应该有几个上游集:
upstream version1.0_server {
server 192.168.1.6:3000;
}
upstream version2.0_server {
server 192.168.1.6:3001;
}
upstream default {
server 192.168.1.6:3000;
}
有版本1.0、版本2.0和默认服务器列表。
那么你需要根据一定的条件来区分哪些服务是继续进行的。
我们这里根据cookie来区分:
set $group "default";
if ($http_cookie ~* "version=1.0"){
set $group version1.0_server;
}
if ($http_cookie ~* "version=2.0"){
set $group version2.0_server;
}
location ^~ /api {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://$group;
}
如果包含version=1.0的cookie,则使用服务version1.0_server。如果有版本 = 2.0 的 cookie,则使用 version2.0_server 服务。否则,使用默认值。
这样就得到了流量划分,这是一个灰度函数。
然后再次打开容器:
这一次,当你访问http://localhost:83/api/时,你会得到默认的版本。
然后带上version=2.0的cookie,你会看到另一个版本的代码:
这样我们就得到了灰度函数。
但是现在有一个问题:
这个cookie是什么时候设置的?
比如我想通过1.0版本获得80%的流量,通过2.0版本获得20%的流量
其实大部分公司都有灰度配置系统,可以管理比例。不同的版本,那么流量经过本系统后,会返回Set-Cookie header,其中按照比例设置不同的cookie。
例如,如果随机数在0到0.2之间,则设置版本=2.0的cookie,否则,设置版本=1.0的cookie。
这也称为流动着色。
完整的灰度流程如下:
在第一次请求时,流量会按照设定的比例进行随机染色,即设置不同的cookie。
如果您再次访问,您将获得基于cookie的不同版本的代码。
这样就实现了灰度功能,可以用来实现5% 10% 50% 100%等灰度在线机制。
还可用于对产品进行AB实验。
每个公司都使用灰度系统。
概述
新版本代码将采用灰度系统推出。可以逐步加大音量,保证启动过程中不会出现大问题。也可用于产品AB实验。
我们可以使用nginx来实现这些功能。
nginx具有反向代理功能,可以将请求转发到应用服务器,也称为网关层。
我们可以根据cookie中的版本字段来决定将请求转发到本层的哪个服务。
在此之前,我们还需要根据比例对流量进行着色,即生成不同的cookie。
无论多么复杂的灰度系统,底层都是着色流量和基于标签的转发流量两部分。我们可以自己实现一个。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。