upstream块必须定义在http块内,不能放在server或location中;需在nginx.conf的http块中添加upstream定义,并在站点配置的location中用proxy_pass引用,同时必须设置proxy_set_header Host $host等关键头信息。

upstream 块必须写在 http 块里,不能放在 server 或 location 里
宝塔默认的 Nginx 配置中,http 块位于 /www/server/nginx/conf/nginx.conf,而站点配置通常被 include 进 server 块(如 /www/server/panel/vhost/nginx/*.conf)。直接在站点配置文件里写 upstream 会报错:nginx: [emerg] "upstream" directive is not allowed here。
正确做法是:把 upstream 定义放到主配置的 http 块内(推荐加在 include 语句之前),再在站点的 server 块中用 proxy_pass http://your_upstream_name; 引用。
- 打开
/www/server/nginx/conf/nginx.conf,找到http {后第一处空白行 - 插入类似如下定义(注意缩进和分号):
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; } - 保存后,在对应站点配置(如
/www/server/panel/vhost/nginx/your-site.conf)的location / {块中,替换原有root或proxy_pass行为:proxy_pass http://backend_cluster;
proxy_set_header Host $host 必须显式设置,否则后端收不到原始域名
不加这行,Nginx 默认把 Host 改成 upstream 中写的 IP 或域名(如 192.168.1.10),后端应用无法识别请求来自哪个站点,可能导致静态资源 404、HTTPS 跳转异常或 SSO 认证失败。
除了 Host,建议一并补全常用代理头:
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;
这些要放在 location 块里 proxy_pass 之前,且不能重复——宝塔自动生成的反向代理规则里可能已含部分,需手动检查去重。
健康检查不能靠 keepalive 自动实现,得用第三方模块或主动探测
原生 Nginx 的 upstream 不支持自动踢掉宕机节点(即无内置健康检查)。max_fails 和 fail_timeout 只对连接拒绝(connection refused)或超时生效,对服务返回 502/503 或卡死无响应无效。
- 若后端某台机器上应用进程崩溃但端口仍监听,Nginx 会持续转发请求过去,用户看到 502
- 解决办法有两个:
– 编译安装nginx_upstream_check_module(宝塔不原生支持,需手动编译替换二进制)
– 在上游服务侧暴露健康接口(如/health),用外部脚本定期调用 + 修改upstream配置 +nginx -s reload(适合低频变更场景) - 简单应急:加
max_fails=3 fail_timeout=30s至每个server行,至少能应对网络闪断
SSL 终止位置决定是否需要 proxy_ssl_* 系列指令
如果 SSL 在宝塔 Nginx 层终止(即证书上传到宝塔,浏览器 → Nginx HTTPS → 后端 HTTP),无需额外配置 SSL 相关代理参数;但若想让流量从 Nginx 到后端也走 HTTPS(即端到端加密),就必须启用 proxy_ssl* 指令,并确保后端服务有可信证书。
- 常见遗漏项:
proxy_ssl_verify off;(后端用自签证书时必须关校验) -
proxy_ssl_protocols TLSv1.2 TLSv1.3;(避免协商失败) -
proxy_ssl_trusted_certificate /path/to/ca-bundle.crt;(开启proxy_ssl_verify on时必需) - 此时
proxy_pass必须写成https://backend_cluster,且 upstream 中的server地址也要带https://前缀(Nginx 1.19.5+ 支持)
多数中小项目用 Nginx 终止 SSL 更轻量,端到端加密反而容易因证书链或协议不匹配导致 502,调试成本高。
实际跑通的关键不在语法多漂亮,而在 upstream 定义位置对不对、Host 头传没传、后端是否真能响应健康探测——这三个点卡住,负载均衡就只是个摆设。











