金丝雀发布是一种渐进式发布策略,允许你将新版本逐步推送给一小部分用户,以降低发布风险。以下是使用Nginx实现金丝雀发布的几种方法:
这是最简单的金丝雀发布方式,通过配置权重来分配流量。
upstream backend {
server backend_v1.example.com weight=90; # 旧版本,90%流量
server backend_v2.example.com weight=10; # 新版本,10%流量
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
更精确地控制哪些用户访问新版本:
upstream backend_v1 {
server backend_v1.example.com;
}
upstream backend_v2 {
server backend_v2.example.com;
}
server {
listen 80;
server_name example.com;
set $canary "no";
# 检查是否存在canary cookie
if ($http_cookie ~* "canary=true") {
set $canary "yes";
}
location / {
if ($canary = "yes") {
proxy_pass http://backend_v2;
}
if ($canary = "no") {
proxy_pass http://backend_v1;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
map $http_x_canary $backend {
default "backend_v1";
"true" "backend_v2";
}
upstream backend_v1 {
server backend_v1.example.com;
}
upstream backend_v2 {
server backend_v2.example.com;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://$backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
geo $canary {
default 0;
10.0.0.0/8 1; # 公司内网用户访问新版本
192.168.1.100 1; # 特定IP访问新版本
}
upstream backend_v1 {
server backend_v1.example.com;
}
upstream backend_v2 {
server backend_v2.example.com;
}
server {
listen 80;
server_name example.com;
location / {
if ($canary) {
proxy_pass http://backend_v2;
}
if ($canary = 0) {
proxy_pass http://backend_v1;
}
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
map $http_user_agent $backend {
default "backend_v1";
~*chrome "backend_v2"; # Chrome用户访问新版本
~*firefox "backend_v2"; # Firefox用户访问新版本
}
upstream backend_v1 {
server backend_v1.example.com;
}
upstream backend_v2 {
server backend_v2.example.com;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://$backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
你可以组合多种条件来实现更复杂的金丝雀发布策略:
map $http_x_canary$cookie_canary$arg_canary $canary {
default 0;
"truetrue" 1;
"truetrue" 1;
~*true 1;
}
geo $geo_canary {
default 0;
10.0.0.0/8 1;
}
map $canary$geo_canary $backend {
default "backend_v1";
~*1 "backend_v2";
}
upstream backend_v1 {
server backend_v1.example.com;
}
upstream backend_v2 {
server backend_v2.example.com;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://$backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
实施金丝雀发布时,确保:
# 重载Nginx配置
sudo nginx -s reload
通过以上方法,你可以灵活地控制金丝雀发布的粒度,逐步扩大新版本的覆盖范围,确保发布过程平稳可控。