Nginx 里的 upstream 是什么意思?
upstream 是 Nginx 里"后端服务器组"的抽象:upstream 块定义一组后端供 proxy_pass 引用,自带负载均衡(轮询/权重/ip_hash)、健康摘除;概念、示例与 FAQ。
upstream 是 Nginx 对"后端服务器组"的命名——用 upstream 块把一台或多台后端定义成一个逻辑组,proxy_pass 再引用这个组名。 一组机器时它就兼任负载均衡器:默认轮询分发,还能加权、会话粘滞、失败摘除。
基本结构
# 定义:名为 myapp 的后端组
upstream myapp {
server backend1.internal:8080;
server backend2.internal:8080;
server 10.0.0.7:8080 weight=3; # 相对默认权重1,长期请求份额约为3倍,不保证字节或每个窗口精确比例
server 10.0.0.8:8080 backup; # 备用:主力全挂才上
}
# 引用:proxy_pass 到组名
server {
listen 80;
location / {
proxy_pass http://myapp;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
负载均衡策略
upstream myapp {
# 不写 = 轮询(round-robin),按 weight 加权
# least_conn; # 最少连接优先:后端处理时长不均时更好
# ip_hash; # 同一客户端 IP 固定到一台:简单的会话粘滞
# hash $cookie_sessionid; # 按任意键哈希:更精细的粘滞
server ...;
}
容错行为
upstream myapp {
server 10.0.0.7:8080 max_fails=3 fail_timeout=30s;
server 10.0.0.8:8080;
# 在多后端组中,30 秒内符合失败条件的请求达 3 次 → 标记下线 30 秒,期间不再分发
}
配合 proxy_next_upstream(默认对 error/timeout 生效),在符合重试条件且尚可安全重试时可转给下一台;非幂等请求需防止重复副作用——这就是 upstream 相对直接写死单台 proxy_pass http://单台 的核心价值。
单机也要用 upstream 吗?
值得。哪怕组里只有一台,upstream 也给了你:统一的命名(改后端地址只动一处)、后续加机器无缝扩展、单后端组中 max_fails/fail_timeout 不会将唯一后端摘除;upstream 维度变量($upstream_addr、$upstream_response_time、$upstream_status)。
需要比较组内后端时,先把 $upstream_addr、$upstream_status 与 $upstream_response_time 写入访问日志。通过观测云 Nginx 日志采集接入后,按实际格式解析这些字段,再比较各后端的耗时与错误;发生重试时,一次请求可能对应多个上游值,分析前要检查样本。
常见问题(FAQ)
Q:upstream 里能写域名吗?
A:能,但默认只在启动/reload 时解析一次 DNS,域名对应的 IP 变了不会自动更新。需要动态解析时可按版本使用 resolver 加变量;开源 Nginx 1.27.3 起也支持 upstream server 的 resolve 配合共享内存 zone 和 resolver。
Q:upstream 和直接 proxy_pass 到一台机器有什么区别?
A:功能上单台时几乎等价;命名 upstream 组便于扩展多后端负载均衡、被动失败摘除及 backup,单后端不会因 max_fails/fail_timeout 被摘除。直接 proxy_pass 到单个地址也有 $upstream_* 变量;是否使用命名组取决于维护需求。上面的 max_fails 是被动检测,不等于 Nginx Plus 的主动健康检查。
Q:怎么做灰度/按比例分流?
A:用 weight——比如新机 weight=1、老机 weight=9,长期请求份额约 10% 进新版本(不保证短窗口或字节量比例),验证稳定后逐步调平。