CentOS 上 Tomcat 线程池配置优化
一 基线配置与启用共享线程池
- 在 $CATALINA_HOME/conf/server.xml 中定义共享的 Executor,再由 Connector 引用,便于多端口共享同一线程池。
- 典型示例(HTTP 与 HTTPS 分别配置,便于独立观察与调优):
<Executor name="tomcatThreadPool"
namePrefix="catalina-exec-"
maxThreads="500"
minSpareThreads="100"
maxQueueSize="100"
prestartminSpareThreads="true"
maxIdleTime="60000"/>
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
executor="tomcatThreadPool"
connectionTimeout="20000"
redirectPort="8443"
enableLookups="false"
acceptCount="200"
maxPostSize="10485760"
keepAliveTimeout="6000"
maxKeepAliveRequests="500"
URIEncoding="UTF-8"/>
<Connector port="8443"
protocol="org.apache.coyote.http2.Http2Protocol"
executor="tomcatThreadPool"
SSLEnabled="true"
maxThreads="150"
connectionTimeout="20000"/>
- 关键参数建议:
- maxThreads:默认 200,CPU 计算密集可保守,I/O 等待多可适当放大;常见区间 400–800,需压测校准。
- minSpareThreads:建议 maxThreads/4,并开启 prestartminSpareThreads=“true”,减少冷启动抖动。
- maxQueueSize:建议显式设置(如 100–200),避免默认无界队列导致内存与排队失控。
- acceptCount:建议 maxThreads/2,队列满后新连接将被拒绝,保护后端过载。
- maxIdleTime:线程最大空闲时间,建议 60000 ms,平衡资源回收与重建开销。
- protocol:优先 NIO2;启用 HTTP/2 于 8443 端口可提升多路复用与头部压缩能力。
二 从日志定位线程池瓶颈
- 关注 catalina.out / localhost_access_log 与 jstack 的组合证据:
- 访问日志中 HTTP 503/500 增多,且线程池指标接近上限,常见于队列满或线程耗尽。
- 线程转储出现大量线程处于 WAITING/PARKED(如等待业务线程池、数据库连接),说明后端是瓶颈而非 Tomcat 线程。
- 出现 RejectedExecutionException(若应用自定义线程池)或连接被拒绝,多为队列与 acceptCount 配置不足。
- 结合系统指标:CPU 接近 100% 且 RT 上升,多为线程过多引发上下文切换;CPU 空闲但 RT 高,多为 I/O 或下游依赖瓶颈。
- 建议做法:先用压测建立基线,再小步调整参数,每次只变更 1–2 个参数并观察 10–15 分钟。
三 参数整定方法与示例
- 基线设定(示例为 16 核 通用服务):
- maxThreads:从 (核心数×2 + 1) 起步,如 64;I/O 密集可逐步放大至 128/256/512 并压测验证拐点。
- minSpareThreads:建议 maxThreads/4,并开启 prestartminSpareThreads。
- acceptCount:建议 maxThreads/2,队列满后拒绝新请求以保护系统。
- maxQueueSize:建议 100–200,避免无界队列导致 OOM 或雪崩。
- 场景化示例:
- 计算密集(低延迟、低外部依赖):maxThreads≈核心数×2,队列与 acceptCount 保守。
- I/O 密集(数据库/远程调用多):maxThreads 适度放大,配合连接池、超时与熔断。
- 突发流量(秒杀/活动):acceptCount 适度放大,队列与线程上限联动,避免级联雪崩。
- 调参顺序建议:先定 maxThreads → acceptCount → maxQueueSize → minSpareThreads,每次压测后评估 RT、TPS、错误率、CPU/内存。
四 操作系统与 JVM 配套优化
- 文件描述符与内核网络:
- 提升进程可打开文件数:在 /etc/security/limits.conf 设置如 nofile 65536。
- 提升内核连接与队列能力:在 /etc/sysctl.conf 设置如 net.core.somaxconn 65535,并启用 net.ipv4.tcp_tw_reuse=1(按需)。
- 容器与 APR(可选):
- 若前端有 Nginx/Apache,可关闭 Tomcat 内置压缩,由反向代理统一处理,降低 Tomcat CPU 压力。
- 安装 APR/native 后可使用 Http11AprProtocol,提升静态资源与网络 I/O 性能。
- JVM 与 GC:
- 固定堆大小避免抖动:如 -Xms4g -Xmx4g;响应时间敏感可选 G1GC,如 -XX:+UseG1GC -XX:MaxGCPauseMillis=200;吞吐优先可选 ParallelGC。
五 快速排错清单
- 线程池满、RT 飙升:先检查下游依赖(DB/缓存/外部 API)是否成为瓶颈;适当增大 maxThreads 与 acceptCount,并配合熔断/限流。
- 队列无限增长或 OOM:显式设置 maxQueueSize,并监控队列占用比例,超过阈值及时告警。
- 大量 TIME_WAIT:优化连接复用与超时(如 keepAliveTimeout、maxKeepAliveRequests),必要时调整内核 tcp_tw_reuse。
- 启动慢或熵不足:在 $JAVA_HOME/jre/lib/security/java.security 将 securerandom.source 改为 /dev/urandom,或安装并启用 rng-tools 提升熵池。