核心是启用upstream keepalive连接池并配套proxy_http_version 1.1和proxy_set_header Connection "",使Nginx复用后端TCP连接,避免每请求新建连接导致Tomcat高频创建线程;需合理设置keepalive、keepalive_requests、keepalive_timeout及proxy_socket_keepalive,并匹配Tomcat的connectionTimeout与线程池参数。

核心是让 Nginx 复用后端连接,避免每个请求都新建 TCP 连接并触发 Tomcat 新建线程处理——这能直接缓解 Tomcat 线程池的高频创建/销毁压力。
必须启用 upstream keepalive 连接池
Tomcat 默认对每个新 TCP 连接都会分配一个线程(尤其在 BIO/NIO 模式下),而 Nginx 默认每请求建连,等于每请求“逼”Tomcat 启一个线程。解决办法是在 upstream 块中显式配置:
- keepalive 64:每个 worker 进程为该 Tomcat 实例缓存最多 64 个空闲长连接(建议值:按 Tomcat 单实例 maxThreads 的 60%~80% 设,如 maxThreads=200,则设 120~160)
- keepalive_requests 1000:单个长连接最多转发 1000 次请求再关闭,避免低频连接长期占着线程却不干活
- keepalive_timeout 25s:空闲连接保留 25 秒,需比 Tomcat 的 connectionTimeout(如 30s)略短,防止被后端先断开
配套代理层协议与头信息清理
只配 keepalive 不够,Nginx 必须用 HTTP/1.1 并清除 Connection: close 才能让 Tomcat 把它当持久连接对待:
- 在 location 或 server 块中加:proxy_http_version 1.1
- 加:proxy_set_header Connection ""(清空该 header,不传 close,也不手动设 keep-alive)
- 确保 Tomcat Connector 配置了 connectionTimeout="30000"(≥30s),且未启用 disableUploadTimeout=false 等干扰项
匹配 Tomcat 线程池实际承载能力
上游连接复用率再高,若 Tomcat 线程池本身过小或参数不合理,仍会排队或拒绝:
- 推荐使用 NIO2 连接器(
protocol="org.apache.coyote.http11.Http11Nio2Protocol"),异步模型更适配长连接复用场景 - 调大 maxThreads="300"(非盲目堆数量),同时设 minSpareThreads="50" 减少突发时线程创建延迟
- 检查 acceptCount(队列长度),设为 200~500,避免连接直接被拒;但注意它不消耗线程,只是排队缓冲
补充 socket 层保活防静默断连
跨公网或经防火墙时,空闲连接可能被中间设备悄无声息地 kill,导致 Nginx 认为连接可用、实际发包失败,最终触发 Tomcat 新线程重试:
- 在 upstream 块中加:proxy_socket_keepalive on 60s 5s 3
- 含义:连接空闲 60 秒后开始探测,每 5 秒发一次 TCP keepalive 包,连续 3 次无响应即关闭 socket
- 该机制独立于 HTTP keep-alive,专治“连接假存活”问题,间接减少 Tomcat 异常线程堆积



















