Nginx负载均衡需正确配置upstream、proxy_pass联动,重载配置而非重启,并设置weight、max_fails、fail_timeout、keepalive及必要header;开源版无主动健康检查,需手动保障后端可达性与流量分散验证。

负载均衡不是加个 upstream 就能用
宝塔面板里直接在 Nginx 配置中写 upstream 块,不等于真能分发流量——Nginx 进程必须重新加载配置,且后端服务得真实可通。很多人配完发现请求全打到一台机器上,或者 502 满天飞,问题往往出在 upstream 和 server 块没联动好。
实操建议:
- 先确认所有后端服务器已部署好服务,并能被宝塔所在机器
curl -I http://ip:port通;不通就别往下走 - 在宝塔「网站」→「设置」→「配置文件」里添加
upstream块,**必须放在http块内,不能塞进server里** - 反向代理的
proxy_pass必须指向upstream定义的名字,比如proxy_pass http://my_backend;,不是 IP - 改完点「保存」后,**手动点「重载配置」(不是重启)**,否则 upstream 不生效
upstream 里的 weight、max_fails、fail_timeout 怎么设才靠谱
默认轮询(round-robin)看似简单,但线上扛不住波动。比如某台后端内存吃紧响应变慢,Nginx 还继续往里塞请求,只会雪上加霜。这些参数不是摆设,是控制故障转移节奏的关键。
实操建议:
-
weight控制流量比例,但别设成 100:1 这种极端值——小权重机器容易因单次超时就被踢出,反而失衡 -
max_fails=3是常见起点,但若后端是 PHP-FPM 类短连接服务,建议调低到1或2,避免失败累积延迟感知 -
fail_timeout=10s表示连续失败后暂停 10 秒,这个时间要略大于你后端平均响应耗时,否则刚恢复就被判“又挂了” - 务必加
keepalive 32;在 upstream 内(Nginx 1.15.3+),否则长连接复用失效,连接数暴涨
宝塔里 proxy_set_header 容易漏掉 Host 和 X-Real-IP
不显式设置,后端收到的 Host 可能是 upstream 名字(如 my_backend),Remote-Addr 会变成 Nginx 本机 IP。你的日志、鉴权、CORS 全乱套。
实操建议:
- 在 proxy_pass 所在的
location块里,**必须加这两行**:proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr; - 如果后端依赖
X-Forwarded-For做限流或地域判断,补上:proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 别信宝塔「反向代理」快捷配置页——它默认不写
Host,点了就以为万事大吉,结果后端收不到原始域名
健康检查只能靠第三方模块或自己轮询
Nginx 开源版原生 upstream **没有主动健康检查**(active health check)。所谓“自动剔除”,只是靠请求失败触发的被动摘除(max_fails)。等它发现挂了,可能已经积压几十个超时请求。
实操建议:
- 要么上商业版 Nginx Plus(有
health_check指令),要么用开源替代方案:比如编译安装nginx_upstream_check_module,但宝塔不支持一键集成,得手动操作 - 更现实的做法:在 upstream 外加一层脚本,用
curl定期探活,生成临时配置并 reload —— 简单粗暴,但得确保 reload 不中断现有连接 - 如果后端本身有 /health 端点,至少把
proxy_next_upstream error timeout http_500 http_502 http_503;加上,让 5xx 也参与容错
upstream 的坑不在语法,而在它和网络、后端状态、Nginx 生命周期的耦合。配完别急着上线,用 ab 或 hey 模拟并发,抓包看请求是不是真分散了,再查后端 access.log 的 IP 分布。漏掉这步,等于裸奔。


















