核心是让连接“该断时断、该复用时复用”,必须分角色、分方向精准配置三类超时参数:proxy_connect_timeout建议1–3秒,proxy_send_timeout设10–20秒,proxy_read_timeout应略大于后端心跳间隔(如60–90秒)或websocket场景设86400;启用upstream keepalive需配套proxy_http_version 1.1和proxy_set_header connection "",并协同后端keepalivetimeout设置,避免生命周期错位。

核心是让连接“该断时断、该复用时复用”,不能靠等超时硬扛。问题本质不是 Nginx 不放,而是上下游连接生命周期没对齐——客户端、Nginx、后端服务三者在空闲判断、关闭触发、资源回收上节奏不一致。
精准设置三类超时参数
超时不是越大越好,也不是统一设成一样,必须分角色、分方向配置:
- proxy_connect_timeout:控制建连阶段,建议 1–3 秒。过长会让失败连接卡住 worker,影响新请求接入
- proxy_send_timeout:Nginx 发完请求后等后端“收妥”的时间,设为 10–20 秒较稳妥。后端若接收慢(如大文件上传),可适当上调
- proxy_read_timeout:最关键的参数,决定长连接空闲多久被断。应略大于后端心跳间隔(例如后端 ping/pong 每 30 秒一次,则设为 60–90 秒);WebSocket 场景常见设为 86400(24 小时),但前提是后端真能稳定维持
启用并合理配置 upstream keepalive
这是解决连接堆积的底层机制。默认 Nginx 对每个后端只维护短连接,频繁建连会压垮后端 TIME_WAIT 和端口资源:
- 在 upstream 块中显式添加 keepalive 32(数值建议 16–64,视后端并发能力而定)
- 配套在 location 中强制使用 HTTP/1.1:proxy_http_version 1.1
- 清除可能干扰复用的头:proxy_set_header Connection ""
- 避免 Nginx 因收到后端返回的
Connection: close而主动断开复用连接
配合后端服务行为做协同
Nginx 无法单方面“感知”后端是否已准备就绪或正在退出,必须靠约定机制对齐:
- 后端服务自身需设置合理的
keepAliveTimeout(如 Tomcat 的connectionTimeout),且该值应 > Nginx 的proxy_read_timeout,防止服务先断而 Nginx 还在发数据 - Kubernetes 环境下,Pod 退出前需通过 preStop Hook + terminationGracePeriodSeconds 预留清理窗口(如 sleep 30),让 Nginx 有时间把活跃连接自然释放
- 若后端支持健康检查,应在 upstream 中启用:health_check interval=10s fails=3 passes=2,及时剔除无响应节点
按场景选对负载均衡算法
轮询(round-robin)在长连接下容易导致连接倾斜——老连接一直挂在某台机器上,新请求却不断打过去:
- 优先用 least_conn:Nginx 会选当前活跃连接数最少的后端,天然适配长连接场景
- 需要会话保持时,慎用 ip_hash(局域网用户易扎堆);更推荐后端共享状态 + 加权轮询,兼顾伸缩性与一致性
- 高可用要求强的场景,搭配 max_fails=3 fail_timeout=30s,自动隔离异常节点











