7.8.2 反向代理与多后端部署策略

反向代理是Web应用对外入口的核心组件,负责接收客户端请求并转发到后端应用,提供统一访问、负载均衡、健康检查、故障隔离与灰度发布能力。本节聚焦Nginx多后端部署策略、关键配置与实操排错。

原理草图(入口—上游—实例):

文章图片

关键策略概览:
- 单入口多实例:无状态服务水平扩展,默认轮询。
- 多机房/多可用区:上游分组+权重,跨区容灾。
- 蓝绿/灰度发布:不同上游组按比例切流。
- 读写分离:按URI或方法分发读写请求。

一、安装与基础验证(示例)#

以Ubuntu为例:

# 1) 安装Nginx
sudo apt update
sudo apt install -y nginx

# 2) 启动与检查
sudo systemctl enable --now nginx
systemctl status nginx --no-pager

# 3) 验证对外访问
curl -I http://127.0.0.1

启动后预期:返回 HTTP/1.1 200 OK

二、多后端反向代理配置示例#

文件:/etc/nginx/conf.d/app.conf

upstream app_backend {
    # 默认轮询
    server 10.0.0.11:8080 max_fails=3 fail_timeout=10s;
    server 10.0.0.12:8080 max_fails=3 fail_timeout=10s;
    keepalive 32;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://app_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        proxy_connect_timeout 3s;
        proxy_read_timeout 10s;
        proxy_send_timeout 10s;
    }
}

生效与验证:

sudo nginx -t
sudo systemctl reload nginx

# 连续访问观察后端分发
for i in {1..5}; do curl -s http://app.example.com/health; done

三、常见负载均衡策略与示例#

1) 加权轮询#

upstream app_backend {
    server 10.0.0.11:8080 weight=3;
    server 10.0.0.12:8080 weight=1;
}

说明:权重高的节点分配更多请求。

2) IP Hash(会话保持)#

upstream app_backend {
    ip_hash;
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}

说明:同一客户端IP固定到同一后端,避免会话丢失。

3) 最少连接(需要启用模块)#

upstream app_backend {
    least_conn;
    server 10.0.0.11:8080;
    server 10.0.0.12:8080;
}

四、灰度发布(按比例切流)#

upstream app_v1 {
    server 10.0.0.11:8080 weight=9;
    server 10.0.0.12:8080 weight=9;
}

upstream app_v2 {
    server 10.0.0.13:8080 weight=2;
}

map $http_x_canary $backend_pool {
    default app_v1;
    "1"     app_v2;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://$backend_pool;
    }
}

说明:默认走V1,携带 X-Canary: 1 则命中V2。

测试:

curl -H "X-Canary: 1" http://app.example.com/version
curl http://app.example.com/version

五、读写分离示例(按URI/方法)#

upstream app_read {
    server 10.0.0.21:8080;
    server 10.0.0.22:8080;
}
upstream app_write {
    server 10.0.0.23:8080;
}

server {
    listen 80;
    server_name api.example.com;

    location /api/read/ {
        proxy_pass http://app_read;
    }

    location /api/write/ {
        proxy_pass http://app_write;
    }

    if ($request_method = POST) {
        set $rw_backend "app_write";
    }
}

六、排错与诊断(命令+解释)#

1) 配置语法错误:

sudo nginx -t

若报错,按提示定位到行号修正。

2) 上游不通或超时:

# 检查Nginx到后端端口可达性
nc -zv 10.0.0.11 8080
curl -m 2 http://10.0.0.11:8080/health

若超时,排查后端服务、网络ACL或防火墙。

3) 负载不均:

# 查看访问日志,观察upstream响应
tail -f /var/log/nginx/access.log

建议开启上游日志格式:

log_format upstream_log '$remote_addr $host $request '
                        '$status $upstream_addr $upstream_response_time';
access_log /var/log/nginx/access.log upstream_log;

4) 会话丢失:
- 使用 ip_hashsticky(需模块);
- 应用侧改造为无状态或使用共享会话存储(Redis)。

七、关键参数解释(快速表)#

  • max_fails:失败次数阈值,超过后临时标记不可用。
  • fail_timeout:失败统计窗口与不可用时间。
  • keepalive:复用到后端的连接数,提升吞吐。
  • proxy_*_timeout:连接/读取/发送超时控制。

八、练习#

1) 部署2个后端(可用Python启动HTTP服务),配置轮询并验证分发结果。
2) 配置灰度发布,通过请求头切流,验证旧版/新版命中。
3) 将一个后端停机,观察Nginx的自动摘除与恢复行为。
4) 增加 keepalive 与超时设置,比较QPS与响应时间变化。