nginx长连接反向代理需协同优化client→nginx与nginx→upstream双链路:前者靠keepalive_timeout和keepalive_requests控制复用时长与请求数,后者必须显式配置proxy_http_version 1.1、proxy_set_header connection ""及upstream keepalive参数,并调优超时与系统句柄限制。

核心是控制连接生命周期,而非单纯扩容。Nginx在长连接反向代理场景下,每个客户端连接会对应一个到上游的TCP连接(尤其未启用keepalive复用时),当并发高、响应慢或空闲时间长,极易耗尽后端服务器的可用端口与文件句柄,表现为大量TIME_WAIT堆积、connect timeout、502或“Too many open files”错误。
启用并合理配置 upstream keepalive
这是最直接有效的手段:避免为每个请求新建上游连接,复用已有连接,大幅降低后端端口和句柄消耗。
- 在upstream块中显式开启keepalive,并设合理池大小:
keepalive 32; —— 值不是越大越好,建议为单个worker平均并发请求数的1.2–1.5倍,通常16–64之间较稳妥 - 确保location中强制使用HTTP/1.1并清除Connection头:
proxy_http_version 1.1;
proxy_set_header Connection ''; —— 否则后端返回Connection: close会中断复用 - 若后端是Tomcat等Java应用,需同步调低其
connectionTimeout和keepAliveTimeout,使其略大于Nginx的proxy_read_timeout,避免Nginx连接还活着而上游已关闭
收紧超时参数,加速连接释放
过长的超时会让连接长期滞留,加剧句柄堆积。需按链路实际延迟分层设置:
- proxy_connect_timeout 2s —— 建连失败快判,避免排队等待
- proxy_send_timeout 15s —— 控制发完请求后等待后端接收完成的时间
- proxy_read_timeout 20s —— 设为后端最长业务耗时的1.5–2倍,不建议超过30s
- 禁用非必要重试:proxy_next_upstream error timeout http_500; —— 避免一次失败触发多次建连
限制并发与队列深度,主动控流
光靠超时被动释放不够,必须从源头控制并发压力:
- 用
limit_conn防止单IP打爆:
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 32; - 若使用Nginx Plus或开源版1.23.3+,启用queue机制防雪崩:
queue 128 timeout=3s; —— 超出连接数的请求进入队列等待,超时则直接拒绝 - 对TCP stream代理(如数据库、WebSocket后端),在stream块中用
limit_conn限连接数,并配proxy_timeout 30s及时断开空闲连接
协同优化系统与Nginx资源上限
句柄耗尽往往是系统层、服务层、Nginx层三重限制未对齐的结果:
- 系统级:确认
/proc/sys/fs/file-max≥ 262144,用户级ulimit -n≥ 65536 - systemd服务:在
/etc/systemd/system/nginx.service中添加
LimitNOFILE=65536 - Nginx配置:在main上下文添加
worker_rlimit_nofile 65536; —— 必须≤系统ulimit值 - events块中
worker_connections建议设为5000–10000,不超过系统ulimit的80%,为日志、临时文件等留余量











