Nginx默认轮询实现横向扩展的关键是后端真无状态、配置真轻量、故障感知真及时:会话存Redis、文件上传走OSS、配置中心化;upstream仅写server IP:PORT;启用HTTP健康检查;通过响应时间、5xx率和请求分布验证扩容效果。

用 Nginx 默认轮询实现多台无状态服务器横向扩展,核心不是“配得复杂”,而是让新增机器真正“即加即用、不拖后腿”。关键落在三点:后端真无状态、Nginx 配置真轻量、故障感知真及时。
后端服务必须彻底无状态
轮询能均匀分发的前提,是任意请求落到任意节点都能完整处理。一旦依赖本地状态,扩容反而引发数据错乱或会话丢失。
- 用户会话(如登录态、临时上下文)统一存 Redis,禁用 HttpSession 或静态变量缓存
- 文件上传走 MinIO/OSS,后端不写磁盘临时文件,网关也不做中转存储
- 动态配置(如路由规则、开关项)从 Nacos/Consul 加载,不读本地 application.yml 或环境变量
- 日志、指标、链路 ID 全部打到中心化服务(如 Loki/Prometheus/Jaeger),不依赖某台机器的文件或端口
upstream 配置保持极简,拒绝干扰项
轮询默认启用,加权重、设 hash、标 backup,都会削弱其天然的可预测性和扩展友好性。
- 只写 server IP:PORT,不加 weight、ip_hash、backup、max_conns 等参数
- 新增节点时,追加一行 server 指令,执行 nginx -s reload 即可,长连接不受影响
- 示例配置干净到只有四行:
upstream app_backend {
server 10.0.2.20:8080;
server 10.0.2.21:8080;
server 10.0.2.22:8080;
}
健康检查必须开启,且用 HTTP 探活
没有健康检查的轮询等于盲转——宕机的机器还在收请求,错误率直接拉高。
- 每个 server 行加上 max_fails=2 fail_timeout=30s,让 Nginx 主动探测并临时摘除异常节点
- 后端暴露 /actuator/health(Spring Boot)或自定义 HTTP 健康端点,返回 200 且响应时间 ≤1s
- 避免仅用 TCP 连通性探测,它无法反映业务真实可用性(比如进程活着但 DB 连不上)
扩容效果要靠指标验证,不能凭感觉
加了机器不代表流量就分过去了,更不代表性能提升了。得看数据:
- 监控 upstream_response_time 的 P95,确认新增节点没拖慢整体响应
- 观察 upstream_status 中各节点的 5xx 比率,若某台突增,说明它下游未就绪或配置不同步
- 对比各节点 request count,偏差控制在 ±12% 内才说明轮询生效;偏差过大需查网络延迟或后端处理耗时是否严重不均


















