天天观天下!新版本上线前会做什么?
今天给朋友们分享的是我们的嘉宾- 前端大佬神光的关于基于 Nginx 实现一个灰度上线系统的文章,希望能对大家有所帮助。
以下是大佬原文:
(相关资料图)
软件开发一般不会上来就是最终版本,而是会一个版本一个版本的迭代。
新版本上线前都会经过测试,但就算这样,也不能保证上线了不出问题。
所以,在公司里上线新版本代码一般都是通过灰度系统。
灰度系统可以把流量划分成多份,一份走新版本代码,一份走老版本代码。
而且灰度系统支持设置流量的比例,比如可以把走新版本代码的流量设置为 5%,没啥问题再放到 10%,50%,最后放到 100% 全量。
这样可以把出现问题的影响降到最低。
不然一上来就全量,万一出了线上问题,那就是大事故。
而且灰度系统不止这一个用途,比如产品不确定某些改动是不是有效的,就要做 AB 实验,也就是要把流量分成两份,一份走 A 版本代码,一份走 B 版本代码。
那这样的灰度系统是怎么实现的呢?
其实很多都是用 nginx 实现的。
nginx 是一个反向代理的服务,用户请求发给它,由它转发给具体的应用服务器。
这一层也叫做网关层。
由它负责转发请求给应用服务器,那自然就可以在这里控制流量的分配,哪些流量走版本 A,哪些流量走版本 B。
下面我们实现一下:
首先,我们准备两个版本的代码。
这里创建个 nest 项目:
npxnestnewgray_test-pnpm
把 nest 服务跑起来:
npmrunstart
浏览器访问下:
看到 hello world 代表 nest 服务跑起来了。
然后改下 AppService:
修改下端口:
然后再 npm run start:
浏览器访问下:
现在我们就有了两个版本的 nest 代码。
接下来的问题是,如何用 nginx 实现灰度,让一部分请求走一个版本的代码,一部分请求走另一个版本呢?
我们先跑一个 nginx 服务。
docker desktop 搜索 nginx 镜像(这步需要科学上网),点击 run:
设置容器名为 gray1,端口映射宿主机的 82 到容器内的 80
现在访问 http://localhost:82 就可以看到 nginx 页面了:
我们要修改下配置文件,把它复制出来:
dockercpgray1:/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 目录。
点击 run。
然后看下 files 部分:
可以看到容器内的 /etc/nginx/conf.d 目录标识为了 mounted。
点开看看:
这就是本地的那个文件。
我们在本地改一下试试:
容器内也同样修改了。
在容器内修改这个文件,本地同样也会修改。
也就是说挂载数据卷之后,容器内的这个目录就是本地目录,是同一份。
然后我们访问下 http://localhost:83/api/ 看看:
nest 服务访问成功了。
现在我们不是直接访问 nest 服务了,而是经历了一层 nginx 反向代理或者说网关层。
自然,我们可以在这一层实现流量控制的功能。
前面我们讲负载均衡的时候,是这么配的:
默认会轮询把请求发给 upstream 下的 server。
现在需要有多组 upstream:
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 的,默认的 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 的服务,否则,走默认的。
这样就实现了流量的划分,也就是灰度的功能。
然后我们重新跑下容器:
这时候,你访问 http://localhost:83/api/ 走到的就是默认的版本。
然后带上 version=2.0 的 cookie,走到的就是另一个版本的代码:
这样,我们就实现了灰度的功能。
但现在还有一个问题:
什么时候设置的这个 cookie 呢?
比如想实现 80% 的流量走版本 1.0,20% 的流量走版本 2.0
其实公司内部一般都有灰度配置系统,可以配置不同的版本的比例,然后流量经过这个系统之后,就会返回 Set-Cookie 的 header,里面按照比例来分别设置不同的 cookie。
比如随机数载 0 到 0.2 之间,就设置 version=2.0 的 cookie,否则,设置 version=1.0 的 cookie。
这也叫做流量染色。
完整的灰度流程是这样的:
第一次请求的时候,会按照设定的比例随机对流量染色,也就是设置不同 cookie。
再次访问的时候会根据 cookie 来走到不同版本的代码。
这就实现了灰度功能,可以用来做 5% 10% 50% 100% 这样逐步上线的灰度上线机制。
也可以用来做产品的 AB 实验。
公司里都会用这样的灰度系统。
总结
新版本代码的上线基本都会用灰度系统,可以逐步放量的方式来保证上线过程不会出大问题,也可以用来做产品 AB 实验。
我们可以用 nginx 实现这样的功能。
nginx 有反向代理的功能,可以转发请求到应用服务器,也叫做网关层。
我们可以在这一层根据 cookie 里的 version 字段来决定转发请求到哪个服务。
在这之前,还需要按照比例来给流量染色,也就是返回不同的 cookie。
不管灰度系统做的有多复杂,底层也就是流量染色、根据标记转发流量这两部分,我们完全可以自己实现一个。
最后,欢迎学编程的朋友们加入鱼皮的,和上万名学编程的同学共享知识、交流进步,学习原创项目并享有答疑指导服务。
往期推荐
关键词:
相关新闻
- 天天观天下!新版本上线前会做什么?
- 申论线下班推荐 突破瓶颈,迈向成功!线上公考网课助你逆袭
- 全球观察:562.2亿元!甘肃定西96个招商项目成功签约
- 大宗商品市场“供需两旺、稳中向好” 企业对后市预期良好生产热情高涨|天天微资讯
- 当前信息:针对日本福岛核污染水处置综合评估报告,生态环境部回应
- 【全球新要闻】*ST皇台股东户数下降1.02%,户均持股11.84万元
- 焦点讯息:大型乐舞诗画《国韵·匠心》融合经典与流行打造国风视听盛宴
- 大众汽车将在巴西投资10亿欧元,目标到2027年实现40%增长_热点在线
- 天天速递!眼视光技术专业 长沙这所学校今年开始招生
- 今日观点!加速关键光电技术突破“卡脖子” 华工科技中央研究院进入实体化运营
- 卓胜微实控人离婚引发减持担忧 机构如何研判投资价值?_世界新视野
- 美国烟草零售店张贴警告标志 世界报资讯
- 奔驰全新一代S级曝光!换特斯拉同款“轭式”方向盘 天天播报
- 今日热闻!“牵手门”事件男子仍担任国企高管?官方回应→
- 《科学防灾减灾夺秋粮丰收预案》发布 每日消息
- 环球今日报丨石化煤炭周报:泰昆石化启动印尼北加炼化一体化项目 沙特自愿减产100万桶/日延长一个月
- 天天观点:重返亚洲之巅 中国女篮还有更多梦想
- 环球快看点丨法国总统马克龙:骚乱顶峰已过去 仍需保持警惕
- 全球今亮点!含有叠词的古诗有哪些 带叠词的古诗词
- 朝山村(对于朝山村简单介绍) 天天热闻
- 核桃生产实用技术_关于核桃生产实用技术概略
- 最佳幸运 闪婚至爱新妻(关于最佳幸运 闪婚至爱新妻介绍)_天天最资讯
- 全球能源资讯NO.446(6月30日金属、非金属矿产品报价) 今日看点
- 天天最新:业内人士称对于AR头显而言LCoS硅基液晶比LEDoS硅基LED更有优势