在灰度发布、A/B 测试等场景中,我们常需要将流量按一定比例分发到不同后端服务。Nginx 提供了 split_clients 模块,配合 map 和 proxy_pass,可以轻松实现基于客户端特征的流量比例分配。本文将从 Nginx 安装、Systemd 管理、完整配置到临时调试方案,提供一份可直接复制使用的完整教程。
一、Nginx 安装(Ubuntu 22.04)
说明:以下操作以 root 用户执行。
# 1. 卸载系统自带 nginx
apt remove nginx
apt purge nginx nginx-common -y
# 2. 更新系统并安装编译依赖
sudo apt update
sudo apt install -y libpcre3 libpcre3-dev zlib1g-dev openssl libssl-dev
# 3. 下载并编译安装 Nginx(以 1.29.0 为例)
wget http://nginx.org/download/nginx-1.29.0.tar.gz
sudo tar -zxvf nginx-1.29.0.tar.gz
cd nginx-1.29.0/
./configure --prefix=/usr/local/nginx/
make && make install
默认安装路径为 /usr/local/nginx/,主程序为 /usr/local/nginx/sbin/nginx,配置文件为 /usr/local/nginx/conf/nginx.conf。
二、Nginx 的 systemd 管理文件
创建 systemd 服务文件 /etc/systemd/system/nginx.service:
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s stop
PrivateTmp=true
[Install]
WantedBy=multi-user.target
启用并启动服务:
systemctl daemon-reexec
systemctl enable nginx
systemctl start nginx
三、完整的 Nginx 配置(按 50%:50% 比例分流)
配置文件路径:/usr/local/nginx/conf/nginx.conf
user root;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" "$upstream_addr"';
# 定义 upstream 与 split_clients(保持原逻辑)
upstream backend_primary {
server bigdata.doubbjt.com;
}
upstream backend_secondary {
server bigdata-h101.doubbjt.com;
}
split_clients "${remote_addr}${http_user_agent}" $backend {
50% backend_primary;
50% backend_secondary;
}
# 新增:动态映射 Host 头
map $backend $target_host {
backend_primary "bigdata.doubbjt.com";
backend_secondary "bigdata-h101.doubbjt.com";
default "bigdata.doubbjt.com"; # 兜底策略
}
server {
listen 80;
server_name bigdata-ai.doubbjt.com;
access_log /var/log/nginx/access.log main;
location / {
proxy_pass http://$backend;
proxy_set_header Host $target_host; # 关键修改:动态 Host 头
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}


