Nginx负载均衡需upstream与proxy_pass协同工作:upstream在http块内定义后端池并注册调度算法,proxy_pass在location中通过http://name/调用该池,二者名称必须严格一致,缺一不可。
proxy_pass 和 upstream 不是两个独立运行的模块,而是紧密配合的一对协作机制:upstream 定义后端服务池和调度规则,proxy_pass 是触发调用这个服务池的“开关”。
upstream 负责准备和管理后端服务器列表
它在 Nginx 启动或重载配置时就完成初始化,把所有 server 配置(IP、端口、weight、max_fails、fail_timeout、backup 等)解析并存入内存结构中,并注册好负载均衡算法(如轮询、ip_hash、least_conn)。这个过程只发生一次,不随请求动态变化。
- server 地址可以是 IP:端口、域名、UNIX socket 路径
- 权重 weight 控制请求分发比例,比如 weight=3 和 weight=1 就是 3:1 分配
- max_fails + fail_timeout 组合实现健康检查,失败达到阈值后临时剔除节点
- backup 标记的服务器仅在其他所有节点都不可用时才启用
proxy_pass 是请求转发的执行入口
当某个 location 匹配到请求,且里面写了 proxy_pass http://your_upstream_name;,Nginx 就会激活 upstream 模块,从中选取一台后端服务器,然后由 proxy 模块建立连接、转发请求头与正文、接收响应并返回给客户端。
- proxy_pass 的 URL 中协议必须明确(http:// 或 https://),后面跟的名称必须与 upstream 块名完全一致
- location 路径会影响转发路径:proxy_pass 后不带 URI 时,原始路径会被完整透传;带 URI 则会做路径替换
- 需配合 proxy_set_header 设置 Host、X-Real-IP 等头信息,否则后端可能收不到真实客户端信息
请求处理时的协同动作
每个请求进来后,Nginx 在 content 阶段调用 ngx_http_proxy_handler,该 handler 内部会调用 upstream 的 peer 获取逻辑(如 ngx_http_upstream_get_round_robin_peer),按当前算法选出一个可用后端,再交由 proxy 模块完成网络通信全流程。
- 若选中的后端连接失败或超时,proxy 模块会按配置 retry 次数,每次重新调用 upstream 获取下一个 peer
- keepalive 配置(upstream 内的 keepalive 参数 + proxy_http_version 1.1 + Connection: "")可复用 TCP 连接,减少握手开销
- 长连接队列大小由 upstream 的 keepalive 数值控制,超出后按 LRU 策略淘汰空闲连接
常见配置联动要点
两者必须配合使用才能实现负载均衡,单独写 upstream 不生效,单独写 proxy_pass 指向不存在的 upstream 名称会导致 502 错误。
- upstream 必须定义在 http 块内,不能放在 server 或 location 中
- proxy_pass 只能在 location、if in location、limit_except 上下文中使用
- 如果后端是 HTTPS,proxy_pass 必须写成 https://xxx,且 upstream 中的 server 无需额外声明协议
- 调试时可通过 error_log 设置 debug 级别,观察 upstream 选 peer 和 proxy 建连的具体行为