原本站点是这样的反向代理:
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.conf 的 http {} 里,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 # 平滑重载
一句话总结
upstream 放 http {}、proxy_pass 别忘 http://、AI/长任务优先 least_conn。三点一起做好,反代改负载均衡基本一次成。
