nginx负载均衡需注意三点:gunicorn实例必须独立监听不同端口或ip;weight仅在启用加权轮询或least_conn时生效,ip_hash等会覆盖权重;健康检查必须显式配置health_check并提供轻量/health接口,否则节点故障不自动剔除。

直接上结论:Nginx 做负载均衡本身不难,但真正卡住多数人的不是配置语法,而是没意识到 Gunicorn 实例必须独立部署、健康检查必须显式启用、权重在默认轮询下根本不起作用。
nginx upstream 里 weight 参数为什么没生效
你写了 server 10.0.0.2:8000 weight=3,但请求还是均分——这不是 Nginx 抽风,是它压根没进加权逻辑。
- Nginx 默认策略是
round-robin,weight只在least_conn或明确启用加权轮询时才参与调度(1.9.1+ 才稳定支持) -
ip_hash、hash $request_uri等指令会强制覆盖权重,哪怕只写了一行也会让 weight 失效 - 后端服务响应超时或返回 5xx 时,Nginx 默认不自动剔除节点,得配
max_fails+fail_timeout才触发临时下线 - 验证方式:用
curl -I http://your-domain/health多次,看响应头中X-Backend(需自定义添加)或 Nginx access log 中的$upstream_addr分布
Gunicorn 实例必须监听不同端口或 IP,不能只靠进程管理
很多人想用 supervisord 或 systemd 启多个 gunicorn -b 0.0.0.0:8000,结果全 bind 失败——端口被占是表象,本质是没做实例隔离。
- 每个 Gunicorn 进程必须绑定唯一地址:
-b 127.0.0.1:8001、-b 127.0.0.1:8002,或用不同 IP(如10.0.0.2:8000、10.0.0.3:8000) - 别依赖
--preload+ 多 worker 模拟多实例:worker 是同一进程内协程/线程,共享内存和连接池,故障会传染 - 如果用容器部署,确保每个容器暴露独立端口,并在 upstream 中按容器 IP 列出,而非全写
localhost - 启动后务必用
ss -tlnp | grep :800确认每个端口确有对应进程在监听
健康检查不是可选项,而是防止雪崩的关键开关
Nginx 默认不做任何探活,一个 Gunicorn 实例卡死或 OOM 后,流量仍会持续打过去,直到超时堆积引发级联失败。
- 必须在 upstream 块中配
health_check interval=3 fails=2 passes=2(需开启ngx_http_upstream_hc_module,通常已编译进主流发行版) - 后端要提供轻量
/health接口:Flask 示例@app.route("/health") def health(): return "ok",不要查 DB 或调外部服务 - 若用
proxy_next_upstream error timeout http_500,记得同步加proxy_next_upstream_tries 2,否则默认只重试 1 次 - 注意:Gunicorn 日志里大量
Connection reset by peer不代表实例挂了,那是客户端断连,健康检查仍应以 HTTP 状态码为准
真实客户端 IP 透传失败导致限流/日志全乱
所有请求在 request.remote_addr 都显示为 127.0.0.1,不是 Flask/FastAPI 的 bug,是 Nginx 没把头转全,或者 Python 框架不敢信。
- Nginx location 块里至少要这三行:
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 - Flask 必须加
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1),x_for=1表示只信任一级代理(即 Nginx),别设成x_for=3给中间 CDN 留后门 - FastAPI 要用
TrustHeaders中间件,且trusted_hosts=["127.0.0.1"]必须精确匹配 Nginx 所在 IP,["*"]是严重安全隐患 - 验证方式:curl 请求后看 access log 中
$http_x_real_ip字段是否为真实公网 IP
最常被跳过的其实是健康检查的响应路径和 ProxyFix 的信任层级——它们不出错时不显眼,一出就是大面积限流失效或日志无法溯源。别等压测崩了才回头翻 upstream 配置。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











