upstream块必须定义在nginx.conf的http块内,不可置于server或location中,否则启动报错;宝塔用户需手动编辑主配置文件,在http{后插入upstream定义,并在站点配置的location中通过proxy_pass引用,同时配合proxy_next_upstream实现失败重试。

upstream 块必须写在 http 块里,否则 Nginx 启动直接报错:nginx: [emerg] "upstream" directive is not allowed here。宝塔默认把站点配置拆到 /www/server/panel/vhost/nginx/*.conf,这些文件只被 include 进 server 块,不能放 upstream。
upstream 必须定义在主配置的 http 块内,且不能写在任何 server 或 location 里
- 打开
/www/server/nginx/conf/nginx.conf,找到http {后的第一处空白行(推荐加在所有include语句之前) - 插入类似如下内容(注意缩进、分号、无多余空格):
upstream backend_cluster { server 192.168.1.10:8080 weight=3; server 192.168.1.11:8080 weight=1; server 127.0.0.1:8081 backup; } - 保存后执行
nginx -t验证语法;若失败,大概率是缩进错、少分号或写进了子配置文件 - 宝塔「重载配置」按钮有时不触发全局重载,建议手动执行
systemctl reload nginx或nginx -s reload
proxy_pass 必须指向 upstream 名称,不能写死 IP
- 在站点配置文件(如
/www/server/panel/vhost/nginx/example.com.conf)的location / {块中,删掉原有的root、index、fastcgi_pass等本地服务指令 - 替换为:
proxy_pass http://backend_cluster; 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_set_header X-Forwarded-Proto $scheme;
-
proxy_pass后的名称(backend_cluster)必须与upstream块名完全一致,大小写敏感 - 宝塔自动生成的反向代理规则里可能已含部分
proxy_set_header,需手动检查去重,重复会导致 Nginx 启动失败或 Header 异常
proxy_next_upstream 是开源版唯一可用的“健康检查”兜底机制
- Nginx 开源版原生不支持主动心跳探测(
check指令无效,宝塔默认未编译nginx_upstream_check_module) -
max_fails和fail_timeout只对连接拒绝、超时生效,对后端返回502/503或假死无响应完全无效 - 必须配合
proxy_next_upstream让失败请求自动转发:proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
- 该指令要放在
location块中proxy_pass之后(顺序不能颠倒) - 若后端某节点进程崩溃但端口仍监听,Nginx 会持续转发并返回
502,用户感知就是卡顿+错误页,此时仅靠max_fails无法规避
Host 头必须用 $host,不是 $http_host
-
proxy_set_header Host $http_host在负载均衡场景下危险:它可能带端口(如example.com:8080)、为空、或被客户端篡改 -
$host只取请求中的域名部分,稳定可靠,后端路由、HTTPS 跳转、SSO 认证才不会出错 - 如果后端是 Node.js(Express/Koa)、Python(Django/Flask),默认不信任代理头,必须显式启用信任:
- Express:
app.set('trust proxy', true) - Django:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')+USE_X_FORWARDED_HOST = True
- Express:
真正起作用的只有 http 块里的 upstream + 站点 location 中的 proxy_pass 和 proxy_next_upstream。其他所谓“健康检查”“界面勾选连接池”全是障眼法——keepalive 只复用 TCP 连接,和故障转移毫无关系。











