G
Q
Q
and
M
E

nginx灰度系统

灰度系统简介

一般软件开发都不是最终版本交付,而是有一个版本接着一个版本的迭代

新版本上线之前都会经过测试,但就算这样,也不能保证上线没有问题

所以,一般上线新版本代码都是通过灰度系统

灰度系统可以将流量划分成多份,一份走新版本代码,一份走老版本代码

而且灰度系统支持设置流量的比例,比如可以把走新版本代码的流程设置为5%,没有问题再放到10%,50%,直到全量

这样可以把出现问题的影响降到最低

如果直接迭代新版本代码,出现线上问题,就是大事故

而且灰度系统不止这一个用途,比如产品不确定某些改动是不是有效的,就要做AB实验,也就是要把流量分成两份,一份走A版本代码,一份走B版本代码

这样的灰度系统如何实现呢?

其实很多都是用nginx实现的

nginx是一个反向代理的服务,用户请求发送给它,由他转发给具体的应用服务器

这一层也叫网关层

由他负责转发请求给应用服务器,那自然就可以在这里控制流量的分配,哪些流量走版本A,哪些流量走版本B

 

通过nginx实现灰度系统

首先我们准备两个版本的代码:

npx nest new gray_test -p npm

更改下AppService:

然后修改一下运行端口:

将这个项目跑起来:

可以看到,运行在3001端口,返回了Hello World! 1111

 

再使用相同的方法新建一个项目,但是不修改文件内容

现在我们就有了两个版本的nest代码

接下来,使用nginx实现灰度,让流量分成两部分,走不同的代码版本

我们先使用docker跑一个nginx镜像,设置容器名为gray1,端口映射宿主机的82到容器内的80:

现在访问本机的82端口就可以看到nginx界面了:

我们修改下nginx的配置文件/etc/nginx/conf.d,添加如下配置:

location ^~ /api {
    rewrite ^/api/(.*)$ /$1 break;
    proxy_pass http://192.168.1.6:3001;
}

这段配置就是加了一个路由,把/api开头的请求转发给 http://宿主机IP:3001这个服务,使用了rewrite把url重写了,比如/api/xxx变成了 /xxx

当我们访问 http://localhost:83/api/时,请求就被转发到了3001端口:

现在我们不是直接访问nest服务了,而是经历了一层nginx反向代理或者说网关层:

我们可以在nginx这一层实现流量控制

在nginx中配置负载均衡是这样的:

默认会轮询把请求发给 upstream下的server;

 

而现在实现灰度系统则需要多组upstream:

upstream version1.0_server {
    server 192.168.1.6:3001;
}
 
upstream version2.0_server {
    server 192.168.1.6:3002;
}

upstream default {
    server 192.168.1.6:3001;
}

有版本1.0、版本2.0,默认的server。
然后需要根据某个条件来区分转发给哪个服务

我们这里根据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 的服务,有 version=2.0 的 cookie 就走 version2.0_server 的服务,否则,走默认的。

这样就实现了流量的划分,也就是灰度的功能

然后重启启动下容器,然后访问下:

可以看到流量走到了默认版本

然后带上 version=2.0 的 cookie,走到的就是另一个版本的代码:

如果带上的是version=1.0,则访问的是1.0版本的代码:

 

这样我们就实现了灰度功能

但现在还有一个问题:

什么时候设置这个cookie呢

其实公司内部一般都有灰度配置系统,可以配置不同的版本的比例,然后流量经过这个系统之后,就会返回 Set-Cookie 的 header,里面按照比例来分别设置不同的 cookie。

比如随机数载 0 到 0.2 之间,就设置 version=2.0 的 cookie,否则,设置 version=1.0 的 cookie。

这也叫做流量染色。

完整的灰度流程是这样的:

第一次请求的时候,会按照设定的比例随机对流量染色,也就是设置不同 cookie。

再次访问的时候会根据 cookie 来走到不同版本的代码。

其中,后端代码会根据 cookie 标识来请求不同的服务(或者同一个服务走不同的 if else),前端代码可以根据 cookie 判断走哪段逻辑。

这就实现了灰度功能,可以用来做 5% 10% 50% 100% 这样逐步上线的灰度上线机制。

也可以用来做产品的 AB 实验。

公司里都会用这样的灰度系统。

posted @ 2023-12-28 11:35  sy0313  阅读(25)  评论(0编辑  收藏  举报