应精简upstream块数量、控制单块服务器数在32台以内、优先使用内置负载算法、禁用未用upstream和健康检查,并采用map变量路由与动态发现机制优化性能。

在 Nginx 中,upstream 块用于定义后端服务器组,其配置方式直接影响请求分发效率、内存开销和运行时检索性能。尤其在大规模部署中(如数百个 upstream 块或每个块含数十台服务器),不当配置会显著增加内存占用,并拖慢 upstream 查找(例如通过 proxy_pass http://name 匹配目标)的速度。
精简 upstream 块数量,避免“一个服务一个 upstream”
每个 upstream 块在 Nginx 启动时被解析为独立的共享内存结构,包含服务器列表、状态变量、健康检查上下文等。即使空定义(如仅 upstream dummy { }),也会占用数百字节基础内存。高频增删 upstream(如自动化脚本每发布一次就加一个)极易导致内存碎片和查找延迟。
- 按服务角色或协议类型聚合:将同集群、同健康检查策略、同负载算法的后端归入同一个 upstream,例如
upstream api_backend统一承载所有 v1/v2 REST 接口实例 - 用变量动态路由替代多 upstream:配合
map指令实现运行时解析,例如根据$host或$request_uri映射到不同后端地址,减少静态 upstream 数量 - 禁用未使用的 upstream:Nginx 不支持热删 upstream,但可通过注释 + reload 规避冗余加载
控制单个 upstream 内服务器数量,合理设置 keepalive
每个 server 条目在 upstream 中以链表节点形式存储,检索时间与节点数呈线性关系;同时,每个 active 连接都会关联 upstream 上下文,过多 server 会放大连接池管理开销。
- 单个 upstream 的 server 数建议控制在 32 台以内;超规模场景应拆分为多个逻辑 upstream(如按机房
api_nj/api_sz),再由外部逻辑(如 geo 或 map)调度 - 启用
keepalive时,避免设置过大的连接池(如keepalive 1024),实际可用连接受系统文件描述符和 upstream server 处理能力限制,通常 32–256 更稳妥 - 移除已下线但未清理的 server 行,Nginx 不自动剔除 dead server,残留条目仍参与哈希/轮询计算
优先使用 hash/ip_hash/least_conn 等内置算法,慎用自定义指令
部分第三方模块(如 nginx-upstream-jvm-route)或复杂 Lua 路由逻辑会在每次请求时触发全量 upstream 遍历或字符串匹配,大幅降低检索效率。
- 内置算法(如
hash $remote_addr consistent)编译为高效 C 实现,查找为 O(1) 或 O(log n),且支持共享内存缓存 - 如需基于 header 或 cookie 路由,优先用
map提前解析为变量,再配合hash $mapped_key,而非在proxy_pass中调用 Lua 函数实时计算 - 禁用不必要的健康检查:对短生命周期服务(如 FaaS 后端),关闭
health_check可减少定时扫描和状态同步开销
启用 upstream 动态发现时,选择轻量级机制
静态配置虽稳定,但扩展性差;而全量动态方案(如频繁 reload 或集成 Consul Template 生成数百 upstream 块)反而加重负担。更优路径是“核心静态 + 局部动态”。
- 采用
nginx-plus的resolver+ 变量 DNS 解析(如proxy_pass http://$backend),配合 TTL 缓存,避免 upstream 结构体膨胀 - 开源版可用
lua-resty-upstream-healthcheck+balancer_by_lua_block实现运行时 server 列表热更新,仅维护一个 upstream 结构,内部 list 动态替换 - 避免在 init_by_lua* 中重复初始化 upstream 数据,应在 worker 初始化阶段一次性加载并共享


















