Nginx 反向代理 灰度发布 配置详解
最近公司项目要上灰度发布,本来想着找个现成的网关方案,什么 K8s + Istio 之类的,结果一算成本和复杂度,算了,咱们这小体量,Nginx 自己配一下就够了。折腾了两天,踩了几个坑,把实测可用的方案记录一下,免得下次又忘了。
什么是灰度发布
简单说就是新版本代码部署上去之后,不是一刀切把所有流量都切过去,而是先放一小部分用户(比如 5%)到新版本上,观察个几天没问题,再逐步放大比例,最后全量。这样做的好处很明显,万一新版本有 bug,影响面也只有那一小撮人,不至于全线崩盘。
常见的灰度策略有几种:按比例随机分流、按 Cookie 分流、按 IP 分流、按 Header 分流。下面挨个说说怎么在 Nginx 里实现。
方式一:按比例分流(最简单粗暴)
利用 Nginx 的 split_clients 模块,按哈希值把流量切分:
http {
split_clients "${remote_addr}${uri}" $backend_pool {
10% backend_new;
* backend_old;
}
upstream backend_new {
server 192.168.1.10:8080;
}
upstream backend_old {
server 192.168.1.20:8080;
}
server {
listen 80;
location / {
proxy_pass http://$backend_pool;
}
}
}
这里用的是 remote_addr 加 uri 做哈希,好处是同一个用户访问同一个页面,基本会稳定落在同一个后端上。要是只写 ${remote_addr},多个人共用一个出口 IP 的情况(比如公司内网)就一起被切过去了,这个看业务接受度吧。
改比例的时候直接把 10% 改成 30%、50%,reload 一下就行,很方便。
方式二:按 Cookie 分流(推荐给内部测试用)
如果想让指定的测试人员先体验新版本,Cookie 方式最省心:
map $cookie_gray_version $backend_pool {
default backend_old;
"v2" backend_new;
}
server {
listen 80;
location / {
proxy_pass http://$backend_pool;
}
}
测试的同学在浏览器里设置一下 Cookie(控制台里敲 document.cookie="gray_version=v2" 就行),刷新页面就进新版本了,其他人完全无感知。放量的过程就是通知更多人加上这个 Cookie,等验证得差不多了再切比例。
方式三:按 Header 分流(配合网关或 App 用)
App 端或者有自建网关的场景,一般习惯用 Header:
map $http_x_gray_tag $backend_pool {
default backend_old;
"beta" backend_new;
}
逻辑和 Cookie 版一样,只是判断的字段换成了 X-Gray-Tag。
会话保持的问题
这里有个大坑要提醒一下:如果你的应用是有登录态的,灰度切过去之后,用户的 session 得两套后端都能认,不然用户会被莫名踢下线。我们当时就遇到这个问题,新版本把 session 存储从本地改成了 Redis,结果灰度期间新版本读不到旧 session,用户一刷新就掉登录。
解决办法要么提前统一 session 存储,要么在灰度期间用 proxy_cookie_path 之类的手段做点兼容,总之提前想好,别上线当天手忙脚乱。
一些细节
- 改完配置记得
nginx -t先测一下,别 reload 出语法错误导致整个服务挂掉,这锅背不起。 - 日志里建议把
$backend_pool加到log_format里,方便排查“为啥这个用户走到新版本了”这种问题。 - 灰度期间新旧版本的监控要分开看,不然新版本的报错容易被老版本的大盘数据稀释掉。
整体下来,Nginx 做灰度发布完全够用,配置也不复杂,小团队没必要一上来就上重型网关。
评论
还没有评论。
发表评论
提交后评论将经过自动审核,审核通过后公开展示。