nginx通过upstream实现微服务流量分发:静态配置用dns+weight+健康检查+backup,按业务选轮询/least_conn/ip_hash等策略,透传host/x-real-ip/x-request-id等头信息;动态场景则对接consul/nacos或用check_module、ci/cd自动更新配置。

直接在 Nginx 的 http 块中定义 upstream,并结合微服务特性选对策略、加健康检查、透传关键信息,就能有效解决多实例流量分发问题。静态配置够用,但面对频繁扩缩容,得引入动态机制。
定义 upstream 服务器组,适配微服务部署方式
微服务实例常运行在容器或云环境中,IP 可能变化,因此 upstream 配置需兼顾灵活性和稳定性:
- 用 DNS 名称代替固定 IP(如
server user-service:8080;),配合resolver指令实现定期刷新,适合 Kubernetes 或 Docker Compose 场景 - 若实例性能不均,用
weight参数区分处理能力,例如高配节点设weight=5,普通节点设weight=2 - 每个
server行加上max_fails=3 fail_timeout=30s,让 Nginx 主动识别失联节点并临时屏蔽,避免请求打空 - 保留
backup节点作兜底,仅当所有主节点不可用时才启用,防止雪崩
选择合适调度算法,匹配业务特征
微服务不是“一刀切”,不同服务对会话、延迟、连接数敏感度不同:
- 无状态 API(如订单查询):默认轮询或
least_conn更稳妥;后者在长连接或响应时间波动大时,能减少单节点积压 - 带 Session 的管理后台:启用
ip_hash,确保同一用户始终落在同一实例,避免重复登录或状态丢失 - 缓存一致性要求高的服务(如商品详情):可借助 OpenResty + Lua 脚本按
$request_uri哈希,把相同路径请求固定到同一后端
反向代理配置要透传上下文,支撑链路追踪与限流
只转发请求不够,下游微服务需要原始访问信息才能做日志、鉴权、熔断等:
-
proxy_set_header Host $host;保留原始域名,避免后端路由错乱 -
proxy_set_header X-Real-IP $remote_addr;和X-Forwarded-For $proxy_add_x_forwarded_for;向后传递真实客户端 IP -
proxy_set_header X-Request-ID $request_id;(需random_index或lua-resty-random生成)用于全链路追踪 - 加上
proxy_next_upstream error timeout http_502 http_503;,后端异常时自动重试其他节点,提升成功率
应对实例频繁变动:从静态走向动态
当微服务自动扩缩容成为常态,硬编码的 upstream 会迅速过期。此时应升级方案:
- 用 Consul 或 Nacos 作为服务注册中心,Nginx Plus 可通过
upstream_confAPI 动态增删节点;OpenResty 则用 Lua 调用注册中心接口实时拉取健康实例列表 - 轻量级替代:编译加载
nginx_upstream_check_module,开启主动健康检查,并提供 HTTP 接口查看/下线节点 - 纯开源方案:配合 CI/CD 流水线,每次服务注册变更触发配置生成 → Git 提交 → 自动推送到所有 Nginx 节点 →
nginx -s reload,做到分钟级同步











