如何优化Ubuntu Tomcat垃圾回收
小樊
44
2025-12-27 17:01:50
Ubuntu Tomcat 垃圾回收优化实操指南
一 基线与环境准备
- 以systemd托管 Tomcat,设置自动重启与资源限制;为服务配置专用用户与最小权限,分离日志与二进制目录,便于审计与回滚。
- 提升文件描述符与进程数上限:在 /etc/security/limits.conf 增加如“soft/hard nofile 65535”,并在 systemd 服务单元中设置 LimitNOFILE=65535,避免“Too many open files”。
- 优化网络与内核参数(/etc/sysctl.conf 或 sysctl -w):如 net.core.somaxconn=4096、net.ipv4.tcp_max_syn_backlog=4096、net.ipv4.tcp_tw_reuse=1、net.ipv4.tcp_fin_timeout=60,提升高并发连接处理能力。
- 启动熵源优化:安装并启动 rng-tools,或在 $JAVA_HOME/jre/lib/security/java.security 中将 securerandom.source 调整为 /dev/./urandom,缓解应用启动或首次请求因熵不足导致的长时间阻塞。
二 JVM 与 GC 策略
- 堆与元空间:将 -Xms 与 -Xmx 设为相同值(如各为物理内存的1/2,视负载与容器而定),避免运行期扩缩堆带来的抖动;设置 -XX:MaxMetaspaceSize=… 防止元空间无限增长;启用服务器模式 -server。
- 垃圾回收器:优先 G1GC(适合大内存、低停顿场景),并开启 GC 日志与时间戳用于长期观测与容量规划:
- 示例(写入 $CATALINA_HOME/bin/setenv.sh 或 catalina.sh 的 JAVA_OPTS):
- JAVA_OPTS=“$JAVA_OPTS -server -Xms2g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:MaxMetaspaceSize=512m”
- JAVA_OPTS=“$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log”
- 旧版本 JDK 说明:若使用 JDK 8 且无法使用 G1GC,可考虑 Parallel GC;CMS 已在后续 JDK 中被废弃,不建议作为新调优目标。
- 元空间注意:JDK 8 之前使用 -XX:PermSize / -XX:MaxPermSize;JDK 8+ 使用 Metaspace(无 PermGen),应改为 -XX:MaxMetaspaceSize 控制上限。
三 Tomcat 连接器与线程模型
- 协议与并发:使用 NIO/NIO2 或 HTTP/2 提升吞吐;按硬件与压测结果配置 maxThreads、minSpareThreads、acceptCount;关闭 DNS 反查 enableLookups=false;启用 GZIP 压缩 减少传输体积;设置合理 connectionTimeout 与 maxKeepAliveRequests 以平衡连接复用与资源占用。
- 线程池:通过 定义全局线程池,避免每个连接器重复创建线程:
- 示例:
-
- <Connector executor=“tomcatThreadPool” port=“8080” protocol=“org.apache.coyote.http11.Http11Nio2Protocol” … />
- 静态资源与反向代理:将图片、CSS、JS 等静态资源交由 Nginx/CDN 处理,降低后端 Tomcat 负载。
四 监控 日志与压测闭环
- GC 日志与可视化:开启 GC 日志 并使用 VisualVM/JConsole 或 JMX 远程监控堆内存、线程与 GC 情况;结合 Prometheus + JMX Exporter 做长期指标沉淀与告警。
- Tomcat 日志治理:在 conf/logging.properties 将多数组件调至 WARNING/ERROR,必要时采用 AsyncFileHandler 降低线程阻塞;在 conf/server.xml 配置 AccessLogValve 的 rotatable 与 maxDays;使用 logrotate 管理 catalina.out 与 gc.log(按日/按大小轮转、压缩、保留策略),并在轮转后通知 Tomcat 重新打开日志句柄(如 kill -USR1 或 systemd reload)。
- 压测与容量:使用 Apache Benchmark(ab) 或 JMeter 进行压测,基于监控指标(线程池使用率、队列长度、错误率、P95/P99 时延、Full GC 次数)迭代参数;遵循灰度/蓝绿发布与回滚预案。
五 快速检查清单与示例配置
- 快速检查清单
- 服务与资源:systemd 重启策略生效、运行用户最小权限、ulimit -n ≥ 65535、/etc/sysctl.conf 网络参数已加载。
- JVM:-Xms == -Xmx、启用 G1GC、开启 GC 日志、设置 MaxMetaspaceSize。
- 连接器:NIO/NIO2 或 HTTP/2、合理的 maxThreads/acceptCount、enableLookups=false、启用 GZIP、合理 connectionTimeout。
- 日志:AccessLogValve 轮转与保留、logging.properties 级别与异步、logrotate 策略与通知、集中化观测与告警已配置。
- 示例配置片段
- setenv.sh(JAVA_OPTS):
- JAVA_OPTS=“$JAVA_OPTS -server -Xms2g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:MaxMetaspaceSize=512m”
- JAVA_OPTS=“$JAVA_OPTS -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$CATALINA_HOME/logs/gc.log”
- server.xml(连接器要点):
- 提示:以上为通用起点,需结合业务对象生命周期、峰值 QPS、P95/P99 时延与 Full GC 频率,经压测逐步微调;避免将 -Xmx 设置过大导致长时间 GC 停顿与系统内存压力。