nginx 通过 ngx_http_upstream_module 定义后端服务组、ngx_http_proxy_module 执行转发来实现 http 层负载均衡;upstream 必在 http{} 内定义,支持 round_robin、least_conn、ip_hash 等调度策略及 weight、max_fails 等 server 参数;proxy_pass 需正确书写 uri 并配合 proxy_set_header 传递真实请求头;健康检查为被动探测,依赖错误响应自动标记不可用。

Nginx 本身不提供独立的“负载均衡模块”,而是靠 ngx_http_upstream_module 定义后端服务组(即负载分发逻辑),再由 ngx_http_proxy_module 执行实际请求转发——两者配合,才构成完整的 HTTP 层负载均衡方案。
upstream 块是负载分发的核心
upstream 必须定义在 http{} 块内,不能嵌套在 server 或 location 中:
- 每个 upstream 块需起一个唯一名称(如
backend_api),后续通过proxy_pass http://backend_api引用; - 支持多种调度策略:
-
round_robin(默认,加权轮询) -
least_conn(优先分发给当前连接数最少的节点) -
ip_hash(同一客户端 IP 固定路由到同一后端,适合会话保持) -
hash $request_uri consistent(一致性哈希,缓存友好)
-
每个 server 行可配置:
-
weight=2:权重越高,被选中的概率越大; -
max_fails=3:连续失败多少次后标记为不可用; -
fail_timeout=30s:标记为不可用后,多久尝试恢复; -
backup:仅当其他节点全部失效时启用; -
down:手动下线该节点,不参与调度。
示例:
upstream backend_api {
ip_hash;
server 10.0.1.10:8000 weight=3 max_fails=2 fail_timeout=15s;
server 10.0.1.11:8000 weight=1;
server 10.0.1.12:8000 backup;
}
proxy_pass 负责把请求转给 upstream
location 中使用 proxy_pass 指向 upstream 名称,注意写法细节:
- ✅ 正确:
proxy_pass http://backend_api;(末尾无/,保留原始 URI) - ❌ 错误:
proxy_pass http://backend_api/;(末尾有/,会截掉 location 匹配部分,导致路径错乱) - 若 location 使用正则匹配(如
location ~ ^/api/),proxy_pass后不能带 URI,否则报错; - 需配套设置关键请求头,确保后端能拿到真实信息:
proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
典型 location 示例:
location /api/ {
proxy_pass http://backend_api;
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_connect_timeout 10;
proxy_send_timeout 30;
proxy_read_timeout 30;
}
健康检查靠被动探测,不是主动心跳
Nginx 原生不支持主动发 HTTP 请求探测后端健康状态:
- 故障识别依赖被动响应:当某 server 返回
500/502/503/504、连接超时或读取超时,Nginx 自动将其标记为不可用; - 标记后,在
fail_timeout时间内不再转发请求,到期后自动重试; - 如需主动健康检查(如定期 GET
/health),需引入第三方模块(如nginx_upstream_check_module)或改用 OpenResty/Tengine。
实际部署要注意路径处理和超时协同
- URI 传递规则容易出错:
-
location /app/ { proxy_pass http://backend; }→/app/foo转发为/app/foo -
location /app/ { proxy_pass http://backend/; }→/app/foo转发为/foo
-
- 超时参数要合理匹配后端能力:
-
proxy_connect_timeout:建立连接上限(通常 5–10s) -
proxy_send_timeout:发送请求体的间隔上限(如大文件上传需调大) -
proxy_read_timeout:等待后端响应的总时长(应 ≥ 后端最长处理时间)
-
不复杂但容易忽略。











