Ubuntu 上提升 Tomcat 响应速度的系统化做法
一 基线评估与监控
- 明确目标:围绕P95/P99 延迟、吞吐量、错误率、线程池利用率、GC 停顿建立可观测性,先测后调,避免“盲调”。
- 快速定位瓶颈:用系统命令查看端口与连接状态(如 netstat/ss)、进程资源(top/vmstat),确认是CPU、I/O、网络还是数据库限制。
- 开启与规范日志:
- 在 server.xml 配置 AccessLog Valve,记录 rt=request_time、uct/uht/urt 等字段,便于分析端到端耗时。
- 在 logging.properties 将生产环境日志级别调为 WARN/ERROR,减少日志开销;对访问日志可用 cronolog 按日分割。
- 打开 GC 日志 并定期分析,观察停顿与回收频率,指导 JVM 调优。
二 Tomcat 连接器与线程池调优
- 使用独立线程池(Executor)并合理设置:
- 建议将 maxThreads 设为 CPU 核心数 × 100~200(如 4 核 400~800),避免线程过多导致上下文切换激增。
- minSpareThreads 取 maxThreads 的 10%~20% 并开启 prestartminSpareThreads,降低冷启动延迟。
- maxConnections 建议为 maxThreads 的 10~20 倍,以容纳更多等待处理的连接。
- acceptCount 作为等待队列,建议 1000~2000,队列满时新连接将被拒绝,需结合压测确定。
- Connector 关键参数:
- 协议优先 NIO/NIO2;长连接/高并发可考虑 APR(需安装 native 库)。
- 启用 Keep-Alive:如 keepAliveTimeout=60000~120000、maxKeepAliveRequests=100,复用连接减少握手开销。
- 开启 GZIP 压缩(对文本类资源有效),并设置 URIEncoding=UTF-8、enableLookups=false 减少阻塞与编码开销。
示例(server.xml 片段):
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="800" minSpareThreads="80" maxIdleTime="60000"
prestartminSpareThreads="true" maxQueueSize="1000"/>
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
executor="tomcatThreadPool"
maxConnections="10000" acceptCount="1000"
connectionTimeout="20000" keepAliveTimeout="60000"
maxKeepAliveRequests="100"
compression="on" compressionMinSize="2048"
compressibleMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json"
URIEncoding="UTF-8" enableLookups="false"/>
三 JVM 与内存调优
- 堆与元空间:将 -Xms 与 -Xmx 设为相同值(如 4G),避免运行期扩容抖动;-XX:MetaspaceSize/-XX:MaxMetaspaceSize 设为 256M/512M 起步。
- 垃圾回收:优先 G1GC(JDK 9+ 默认),如 -XX:+UseG1GC -XX:MaxGCPauseMillis=200;超大堆(>100GB)可考虑 ZGC(JDK 15+)。
- 启动与稳定性:
- 使用 -Djava.security.egd=file:/dev/./urandom 避免 SecureRandom 初始化阻塞。
- 开启 HeapDumpOnOutOfMemoryError 与 GC 日志,便于排障与回溯。
示例(setenv.sh 片段):
export JAVA_OPTS="$JAVA_OPTS -Xms4g -Xmx4g"
export JAVA_OPTS="$JAVA_OPTS -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
export JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
export JAVA_OPTS="$JAVA_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/tomcat/heap.hprof"
export JAVA_OPTS="$JAVA_OPTS -Xloggc:/var/log/tomcat/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps"
export JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -Duser.timezone=Asia/Shanghai"
四 反向代理与静态资源优化(Nginx 前置)
- 进程与连接:
- worker_processes=auto,worker_connections=10240;Linux 使用 epoll;提高 worker_rlimit_nofile。
- 开启 sendfile、tcp_nopush、tcp_nodelay,提升静态文件与长连接性能。
- 与 Tomcat 的长连接:
- 在 upstream 中配置 keepalive 256~512,并启用 proxy_http_version 1.1、proxy_set_header Connection “”,复用后端连接。
- 压缩与缓存:
- 开启 gzip(级别 1~6,对文本/JS/CSS 有效),静态资源设置 Cache-Control/Expires 与 proxy_cache,减少回源与传输量。
五 Linux 系统与数据库层优化
- 文件描述符与内核网络:
- 提升 fs.file-max 与进程 ulimit -n(如 65535),避免“too many open files”。
- 优化 TCP:net.core.somaxconn、net.ipv4.tcp_max_syn_backlog、net.ipv4.tcp_tw_reuse、net.ipv4.tcp_keepalive_time 等,缓解连接排队与 TIME_WAIT 压力(注意不同内核版本参数差异与风险)。
- 应用与数据访问:
- 使用连接池(如 HikariCP/DBCP)并配置合理的最大连接数与超时;优化 SQL、索引、分页,减少慢查询与锁等待。
- 将静态资源交由 Nginx/CDN,减少 Tomcat 处理与带宽占用。
六 快速落地清单与压测验证
- 快速清单(可直接套用并压测微调):
- 线程池:maxThreads=800(4 核示例)、minSpareThreads=80、acceptCount=1000、maxConnections=10000。
- Keep-Alive:keepAliveTimeout=60000、maxKeepAliveRequests=100;启用 GZIP。
- JVM:-Xms4g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200,开启 GC/HeapDump 日志。
- 系统:ulimit -n 65535;按需调整内核网络参数。
- 反向代理:启用 keepalive 256、静态资源缓存与压缩。
- 压测与验证:
- 以真实流量模型进行渐进式压测(如从 25% 到 100% 峰值),观察 P95/P99、吞吐、错误、线程池与 GC 曲线,按瓶颈逐项微调。
- 持续观测 AccessLog/GCLog,结合 JConsole/VisualVM 或 APM 工具定位代码级热点。