Nginx 反向代理改造成负载均衡:踩坑与正确写法

原本站点是这样的反向代理:

location / {
    proxy_pass http://192.168.5.31:8000;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

后端加机器了,要改成负载均衡。看着简单,但一路踩了两个坑。

步骤一:定义 upstream

轮询模式最简单:

upstream backend {
    server 192.168.5.31:8000;
    server 192.168.5.32:8000;
    server 192.168.5.33:8000;
}

location 里的 proxy_pass 改成:

proxy_pass http://backend;

三种策略怎么选

WebSocket / 长连接:ip_hash

同一个客户端 IP 固定打到同一台机器,session 不会乱:

upstream backend {
    ip_hash;
    server 192.168.5.31:8000;
    server 192.168.5.32:8000;
}

机器性能不同:weight

upstream backend {
    server 192.168.5.31:8000 weight=4;
    server 192.168.5.32:8000 weight=2;
    server 192.168.5.33:8000 weight=1;
}

流量大致按 57% / 29% / 14% 分。

AI 推理、长请求:least_conn

轮询在这种场景很糟糕——某台机器可能同时挤了 5 个几十秒的推理请求,其他机器闲着。least_conn 会挑当前连接数最少的:

upstream backend {
    least_conn;
    server 192.168.5.31:8000;
    server 192.168.5.32:8000;
    server 192.168.5.33:8000;
}

顺手加个健康检查,挂了的自动摘除:

server 192.168.5.31:8000 max_fails=3 fail_timeout=30s;

坑一:upstream directive is not allowed here

改完 reload,直接报:

nginx: [emerg] "upstream" directive is not allowed here
in D:\phpstudy_pro\Extensions\Nginx1.15.11/conf/vhosts/127.0.0.1_8000.conf:24

upstream 只能写在 http {} 块里,不能写进 server {}location {}。而 PHPStudy 类面板的 vhost 文件通常等价于一个 server 配置片段,里面就不能定义 upstream。

正确做法:把 upstream backend {...} 挪进主 nginx.confhttp {} 里,vhost 文件里只放 location

# nginx.conf
http {
    upstream backend {
        least_conn;
        server 192.168.5.31:8000;
        server 192.168.5.32:8000;
    }

    include vhosts/*.conf;
}

坑二:proxy_pass 少了协议头

写成:

proxy_pass backend;

Nginx 会直接报语法错误。proxy_pass 必须带上 http://https://

proxy_pass http://backend;

检查与重载

nginx -t         # 语法检查
nginx -s reload  # 平滑重载

一句话总结

upstreamhttp {}proxy_pass 别忘 http://、AI/长任务优先 least_conn。三点一起做好,反代改负载均衡基本一次成。