7.3.7 实战配置示例与常见问题

本节聚焦反向代理与负载均衡的实战配置与高频问题。包含可执行配置、验证命令、排错步骤与练习,并给出原理草图便于理解请求流向。

原理草图与请求流向#

文章图片

环境准备与安装#

  • 适用系统:CentOS 7/8 或 Ubuntu 20.04+
  • 安装 Nginx(以 CentOS 为例)
# 安装
sudo yum install -y epel-release
sudo yum install -y nginx

# 启动与开机自启
sudo systemctl enable nginx
sudo systemctl start nginx

# 验证版本与配置语法
nginx -v
sudo nginx -t

预期效果:nginx -t 返回 syntax is oktest is successful

实战配置示例#

1) 基础反向代理(单后端)#

场景:将 80 端口请求转发到后端 127.0.0.1:8080

# /etc/nginx/conf.d/reverse_proxy.conf
server {
    listen 80;
    server_name www.example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;                 # 透传原 Host
        proxy_set_header X-Real-IP $remote_addr;     # 真实客户端 IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;  # 协议透传
    }
}

应用配置并验证:

sudo nginx -t
sudo systemctl reload nginx
curl -I http://www.example.com

预期效果:返回 200/301 等正常响应码,后端日志能看到真实 IP。


2) upstream 负载均衡(轮询/权重)#

场景:多节点扩展,权重分配 2:1

# /etc/nginx/conf.d/upstream_lb.conf
upstream app_backend {
    server 10.0.0.11:8080 weight=2 max_fails=3 fail_timeout=10s;
    server 10.0.0.12:8080 weight=1 max_fails=3 fail_timeout=10s;
    keepalive 32; # 复用后端连接
}

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

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

验证负载均衡分布:

for i in {1..10}; do curl -s http://app.example.com/health; done

预期效果:后端日志中请求分配符合权重比例。


3) 连接与超时调优(大文件/慢请求)#

# /etc/nginx/conf.d/timeout_tuning.conf
server {
    listen 80;
    server_name upload.example.com;

    client_max_body_size 200m;

    location /upload/ {
        proxy_pass http://10.0.0.21:8080;
        proxy_connect_timeout 5s;
        proxy_send_timeout 60s;
        proxy_read_timeout 120s;
        proxy_buffering on;
    }
}

验证上传:

curl -F "file=@/path/to/200m.bin" http://upload.example.com/upload/

预期效果:上传不被 413/408/504 拒绝。


4) 会话保持(ip_hash)#

# /etc/nginx/conf.d/sticky_iphash.conf
upstream app_session {
    ip_hash;
    server 10.0.0.31:8080;
    server 10.0.0.32:8080;
}

server {
    listen 80;
    server_name session.example.com;
    location / {
        proxy_pass http://app_session;
    }
}

说明:ip_hash 不支持权重,适合简单会话保持。


5) 灰度发布(按 Header 分流)#

# /etc/nginx/conf.d/canary.conf
map $http_x_canary $upstream_name {
    default        "app_prod";
    "true"         "app_canary";
}

upstream app_prod {
    server 10.0.0.41:8080;
}
upstream app_canary {
    server 10.0.0.42:8080;
}

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

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

验证灰度:

curl -H "X-Canary: true" http://gray.example.com/
curl http://gray.example.com/

预期效果:带头请求进入灰度节点。


6) HTTPS 反向代理(前端 HTTPS / 后端 HTTP)#

# /etc/nginx/conf.d/https_proxy.conf
server {
    listen 443 ssl http2;
    server_name secure.example.com;

    ssl_certificate     /etc/nginx/ssl/fullchain.pem;
    ssl_certificate_key /etc/nginx/ssl/privkey.pem;

    location / {
        proxy_pass http://10.0.0.51:8080;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header Host $host;
    }
}

证书检查:

openssl x509 -in /etc/nginx/ssl/fullchain.pem -noout -dates

7) WebSocket 代理#

# /etc/nginx/conf.d/ws.conf
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

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

    location /ws/ {
        proxy_pass http://10.0.0.61:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_read_timeout 1h;
    }
}

验证握手:

curl -i -N \
  -H "Connection: Upgrade" \
  -H "Upgrade: websocket" \
  -H "Host: ws.example.com" \
  -H "Origin: http://ws.example.com" \
  http://ws.example.com/ws/

预期效果:返回 101 Switching Protocols

常见问题与排查思路(含命令)#

  1. 后端真实 IP 丢失
    - 排查:
grep -n "X-Real-IP" -n /etc/nginx/nginx.conf /etc/nginx/conf.d/*.conf
  • 处理:添加 X-Real-IPX-Forwarded-For,后端解析 X-Forwarded-For 最左侧。
  1. 502/504 网关错误
    - 排查流程:
# 1) 检查后端端口
nc -vz 10.0.0.11 8080

# 2) 查看 Nginx 错误日志
tail -n 50 /var/log/nginx/error.log

# 3) 检查 Nginx 配置
nginx -t
  • 处理:恢复后端服务或调大 proxy_read_timeout
  1. upstream 倾斜
    - 排查:
# 查看后端访问日志分布
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c
  • 处理:权重调整、剔除慢节点、启用 keepalive
  1. 文件上传失败或截断
    - 排查:
grep -n "client_max_body_size" -n /etc/nginx/conf.d/*.conf
  • 处理:增大 client_max_body_size 与读写超时。
  1. 循环代理或 Host 错误
    - 排查:
grep -n "proxy_set_header Host" -n /etc/nginx/conf.d/*.conf
curl -I http://domain/ -L
  • 处理:确认代理未指向自身域名或 80/443 同域互跳。
  1. WebSocket 断连
    - 排查:
grep -n "Upgrade" -n /etc/nginx/conf.d/ws.conf
  • 处理:补全 Upgrade/Connection,延长 proxy_read_timeout
  1. 健康检查不生效
    - 说明:开源 Nginx 仅支持被动健康检查。
    - 替代:使用 max_fails/fail_timeout 或接入外部探活与自动剔除脚本。

命令解释速查#

  • nginx -t:语法检查,防止 reload 失败。
  • systemctl reload nginx:热加载配置,连接不中断。
  • curl -I:仅请求响应头,快速检查状态码。
  • tail -f error.log:实时定位 4xx/5xx 原因。

练习与作业#

  1. 设计一个包含 3 台后端的 upstream,权重为 3:2:1,并验证访问分布。
  2. upload.example.com 的上传限制从 50M 提升到 200M,记录 413 错误消失的过程。
  3. 编写 map 规则,实现根据 User-Agent 分流到灰度节点。
  4. 模拟后端宕机,观察 max_fails/fail_timeout 对请求的影响,并记录恢复流程。