nginx配置upstream的核心答案是:在http块内用upstream指令声明一组后端服务器,再通过server内部的proxy_pass转发到该分组,即可实现负载均衡,Nginx默认按加权轮询分发流量,配合健康检查参数和合理的策略选择,能解决绝大多数高可用场景需求。
nginx upstream配置详解:先把最小可用配置跑起来
初见upstream会有点绕,因为它的配置结构分成两段,第一段定义“后端池子”,放在http块里,跟server块平级,第二段是使用池子,放在location里用proxy_pass指向池子名称。
以下是最小可用的完整配置示例:
http {
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
server {
listen 80;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
这段配置做的事情很直白:当Nginx收到请求后,会根据upstream里的服务器列表,把请求转发给其中一台后端服务器。
upstream块里每个参数都是干什么的
upstream内部的server指令远比看起来复杂,它支持多个参数,按使用频率排列:
- weight:加权轮询权重,默认都是1,比如机器A性能是机器B的两倍,可以给A配weight=2,B保持默认。
- max_fails:允许请求失败的次数,配合超时时间使用,默认1,设为0表示不检查。
- fail_timeout:max_fails记数的时间窗口,也是节点被标记不可用后的冷却时间,默认10秒。
- backup:标记为备份服务器,只有当主服务器全部不可用时才接流量。
- down:标记节点永久下线,常用于灰度发布场景。
一个比较实用的配置时机:在业务高峰期前,如果后端某台机器维护升级,把对应server加个down标记然后reload,比直接改DNS或拔机器安全得多。
nginx upstream轮询和ip_hash区别:选错策略流量会“偏科”
这是配置upstream时最常被问到的问题,也是决定负载是否均匀的关键。
轮询:默认策略,雨露均沾

加权轮询是Nginx的默认行为,每个请求按权重轮流分发,后端机器接收到的请求数量大致保持均衡。
适合场景:后端服务器状态基本无状态,比如纯API服务、静态资源服务器。
ip_hash:同一用户粘在同一个节点
ip_hash基于客户端IP计算哈希值,将请求固定分配到某台后端服务器,这样同一IP的请求总是打到同一台机器上,保证会话连续性。
upstream backend {
ip_hash;
server 192.168.1.10:8080;
server 192.168.1.11:8080;
}
代价也很明显:如果某台后端宕机,对应落在它上面的IP会被重新哈希到其他节点,但哈希算法基于IP分布,节点数变化会造成相当一部分请求重新映射,建议只在需要session保持的场景使用。
least_conn:谁闲着就把请求给谁
least_conn看后端当前活跃连接数,把新请求分给连接数最少的节点,适合请求处理时间差异较大的场景,比如某些接口响应快、某些接口响应慢。
| 策略 | 配法 | 适用场景 | 注意点 |
|---|---|---|---|
| 加权轮询 | 默认 | 无状态API | 节点性能不均时设weight |
| ip_hash | ip_hash; | 有session的Web应用 | 节点扩容会影响映射 |
| least_conn | least_conn; | 长连接、响应时长差异大 | 需要开启keepalive配合 |
| url_hash | hash $request_uri; | 缓存命中率优先 | 需要hash key不变化 |
url_hash是按请求URI做哈希,同一个URL固定落在同一个后端节点,对本地缓存类服务非常友好,行业共识认为,没有通用的最优策略,只能根据业务特性试出来的最合适。
nginx upstream健康检查配置:别让故障节点拖垮整个集群
upstream配置完成后,很多人的第一反应是“这就完了?”默认行为里后端服务器只要被标记为不可用,Nginx会直接跳过它,这是好的一面,但真正的问题在于Nginx如何判断后端已经不可用?

被动健康检查:开源版默认的保底机制
开源版Nginx本身不具备主动探测能力,它做的是被动检查:请求转发到后端失败或超时之后,Nginx才开始记数。
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
}
location / {
proxy_next_upstream error timeout http_502 http_503;
}
proxy_next_upstream是关键,它告诉Nginx在哪些情况下应该尝试下一台后端,这行配置意味着:如果当前后端抛错或超时,Nginx自动把请求转给upstream组里的下一台服务器。不配置这个指令,请求失败就直接返回502,不会做任何重试。
主动健康检查:商业版与OpenResty的玩法
Nginx Plus提供主动健康检查,能定期探测后端端口或URL,提前摘除故障节点,开源版想实现类似效果,有两条路:
- 使用OpenResty(Nginx加Lua扩展)自建探测逻辑。
- 配合Consul、etcd等注册中心,由外部系统定期更新Nginx upstream列表。
近年来,搭配注册中心动态更新upstream的做法越来越普遍,尤其是容器化环境里节点频繁变化,纯粹手工维护server列表根本忙不过来。
场景实战:nginx配置upstream不生效?多半是这四处细节
upstream配置看起来简单,实际踩坑的人很多,结合常见报错场景,做一个排查清单:
proxy_pass的坑:别把URL路径和upstream名混在一起
nginx upstream配置常见误区之一是proxy_pass末尾多了一个斜杠,或者写在upstream后面跟了完整URL路径。
正确写法:
location /api/ {
proxy_pass http://backend;
}
注意proxy_pass后没有斜杠,这样Nginx会把完整的原始URI传给后端,如果写成proxy_pass http://backend/;,则会影响路径传递方式,容易导致后端路由404。
不要把upstream名字当域名用,有人写成proxy_pass http://backend:8080;,但backend并不是实际域名,这会导致无法解析。
upstream位置放错

upstream块必须放在http上下文内,不能写在server块或location块里,如果配置文件里出现“upstream directive is not allowed here”报错,基本都是这个原因。
reload和restart的差别
修改upstream配置后,执行nginx -s reload是平滑加载新配置,不会中断请求。执行restart会造成连接断开,生产环境务必用reload。
与容器化环境配合的坑
当后端是Docker容器时,upstream里的IP不能写容器内部IP,而要写宿主机端口映射后的地址,或使用docker network内可访问的容器名,业务稍微复杂一些的,直接上Consul做服务发现更省心。
nginx配置upstream常见问题解答
为什么我配置了upstream但请求还是固定打到同一条后端?
先检查是否用了ip_hash策略,如果用的是默认轮询,但后端其中一台请求失败率高,连续失败超过max_fails后该节点会被临时移除,流量自然全部打到剩余节点,可以配置max_fails=1 fail_timeout=5s并结合日志确认该节点是否频繁进入冷却状态。
upstream里配置http和https后端能混用吗?
同一upstream组内不建议混用协议,但不同upstream组可以分别配置,转发到HTTPS后端时,proxy_pass写成http://backend即可,Nginx会自动以HTTP方式请求内网后端,如果需要Nginx和后端之间走HTTPS加密,则要配置proxy_ssl_server_name on;和相关证书参数。
长时间运行的WebSocket或大文件上传走upstream会断吗?
会,Nginx默认在60秒内没有数据传输就会断开连接,需要手动调大超时时间,WebSocket场景必须配置proxy_http_version 1.1;加上Upgrade和Connection头,否则WebSocket握手直接失败:
location /ws/ {
proxy_pass http://backend_ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
最后记住一条核心认知:upstream不是高可用的全部,它负责流量转发,真正保证业务不中断的是健康检查参数、重试机制和节点恢复策略,这三点组合起来才构成完整的nginx配置upstream负载均衡方案。
