Code前端首页关于Code前端联系我们

基于Nginx实现灰度在线系统的完整流程

terry 2年前 (2023-09-28) 阅读数 75 #未命名

软件开发一般不会有最终版本,而是从一个版本到另一个版本迭代。

新版本上线前会进行测试,但不保证上线时不会出现问题。

所以,新版本的代码一般都是通过公司内的灰度系统发布。

灰度系统可以将流量分成几部分,一部分使用新版本代码,另一部分使用旧版本代码。 基于 Nginx 实现灰度上线系统的完整流程

并且灰度系统支持调整流量比例。例如,您可以将新版本代码流量设置为5%。如果没问题的话,设置为10%、50%,最后设置为全额的100%。

这可以最大限度地减少问题的影响。

不然一到就全款用完。如果网上出了问题,那将是一场大灾难。

而且灰度系统不仅仅用于这个目的。例如,如果产品不确定某个改动是否有效,就需要进行AB实验,即将流量分为两部分,一部分使用代码版本A,另一部分使用代码版本A代码版本B.版本代码。

灰度系统是如何实现的?

其实很多都是使用nginx实现的。

nginx 是一个反向代理服务。用户请求被发送并转发到特定的应用服务器。 基于 Nginx 实现灰度上线系统的完整流程

该层也称为网关层。

它负责将请求转发到应用服务器,所以你可以控制这里的流量分配,流向版本A的流量和流向版本B的流量。

我们来实现如下:

首先,我们设置两个代码的版本。

在此创建nest项目:

npx nest new gray_test -p npm
基于 Nginx 实现灰度上线系统的完整流程

运行nest服务:

npm run start
基于 Nginx 实现灰度上线系统的完整流程

使用浏览器访问:基于 Nginx 实现灰度上线系统的完整流程

看到hello world,表示nest服务正在运行。

然后更改AppService:基于 Nginx 实现灰度上线系统的完整流程

修改端口:基于 Nginx 实现灰度上线系统的完整流程

然后npm run start:基于 Nginx 实现灰度上线系统的完整流程

浏览器访问:基于 Nginx 实现灰度上线系统的完整流程

现在我们有两个版本的嵌套代码。

下一个问题,如何使用nginx实现灰度,让部分请求走一个代码版本,部分请求走另一个版本?

我们先启动nginx服务。

Docker桌面正在寻找nginx镜像(这一步需要科学上网),点击运行:基于 Nginx 实现灰度上线系统的完整流程

将容器名称设置为gray1,并将端口从主机上的82映射到容器上的80基于 Nginx 实现灰度上线系统的完整流程

现在访问 http://localhost : 82 就可以看到 nginx 页面: 基于 Nginx 实现灰度上线系统的完整流程

我们需要修改配置文件并复制它:

docker cp gray1:/etc/nginx/conf.d ~/nginx-config
基于 Nginx 实现灰度上线系统的完整流程

然后编辑这个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容器:基于 Nginx 实现灰度上线系统的完整流程

容器名为gray2,端口83映射到容器中的80。

定义数据卷,并将本地~/nginx-config目录挂载到容器的/etc/nginx/conf.d目录中。

单击运行。

然后查看文件部分:

可以看到容器中的/etc/nginx/conf.d目录被挂载了。 基于 Nginx 实现灰度上线系统的完整流程

点击查看:基于 Nginx 实现灰度上线系统的完整流程

这是本地文件。

我们尝试在本地更改它:基于 Nginx 实现灰度上线系统的完整流程

容器也以同样的方式更改。 基于 Nginx 实现灰度上线系统的完整流程

如果你在容器中修改这个文件,本地也会被修改。

也就是说,挂载数据卷后,容器中的目录是本地目录,并且是本地目录的副本。

然后访问http://localhost:83/api/,看到:基于 Nginx 实现灰度上线系统的完整流程

nest服务访问成功。

现在我们不直接访问Nest服务,而是经过nginx反向代理层或者网关层。 基于 Nginx 实现灰度上线系统的完整流程

自然,我们可以在这一层实现流控功能。

之前讲负载均衡的时候,配置如下: 基于 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 服务。否则,使用默认值。 基于 Nginx 实现灰度上线系统的完整流程

这样就得到了流量划分,这是一个灰度函数。

然后再次打开容器:基于 Nginx 实现灰度上线系统的完整流程

这一次,当你访问http://localhost:83/api/时,你会得到默认的版本。 基于 Nginx 实现灰度上线系统的完整流程

然后带上version=2.0的cookie,你会看到另一个版本的代码:基于 Nginx 实现灰度上线系统的完整流程

这样我们就得到了灰度函数。

但是现在有一个问题:

这个cookie是什么时候设置的?

比如我想通过1.0版本获得80%的流量,通过2.0版本获得20%的流量

其实大部分公司都有灰度配置系统,可以管理比例。不同的版本,那么流量经过本系统后,会返回Set-Cookie header,其中按照比例设置不同的cookie。

例如,如果随机数在0到0.2之间,则设置版本=2.0的cookie,否则,设置版本=1.0的cookie。

这也称为流动着色。

完整的灰度流程如下: 基于 Nginx 实现灰度上线系统的完整流程

在第一次请求时,流量会按照设定的比例进行随机染色,即设置不同的cookie。

如果您再次访问,您将获得基于cookie的不同版本的代码。

这样就实现了灰度功能,可以用来实现5% 10% 50% 100%等灰度在线机制。

还可用于对产品进行AB实验。

每个公司都使用灰度系统。

概述

新版本代码将采用灰度系统推出。可以逐步加大音量,保证启动过程中不会出现大问题。也可用于产品AB实验。

我们可以使用nginx来实现这些功能。

nginx具有反向代理功能,可以将请求转发到应用服务器,也称为网关层。

我们可以根据cookie中的版本字段来决定将请求转发到本层的哪个服务。

在此之前,我们还需要根据比例对流量进行着色,即生成不同的cookie。

无论多么复杂的灰度系统,底层都是着色流量和基于标签的转发流量两部分。我们可以自己实现一个。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门