CentOS 下 Tomcat 启动速度优化
一 快速定位瓶颈
- 查看 catalina.out 中是否出现如下日志,且耗时明显(例如数秒到数十秒):
org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance … took [55,507] ms
同时检查系统熵值:cat /proc/sys/kernel/random/entropy_avail,若数值很低(如个位数或几十),基本可判定为 SecureRandom 熵不足 导致的启动卡顿。该问题在虚拟机、云主机环境中尤为常见。
二 解决 SecureRandom 熵瓶颈(见效最快)
- 方案 A(快速绕过):在 $JAVA_HOME/jre/lib/security/java.security 中将
securerandom.source=file:/dev/random
改为
securerandom.source=file:/dev/urandom
或在 $TOMCAT_HOME/bin/catalina.sh 的 JAVA_OPTS 中追加:
-Djava.security.egd=file:/dev/urandom
说明:/dev/urandom 为非阻塞熵源,能显著缩短启动时间;在安全合规允许的场景优先采用。
- 方案 B(根治熵不足):安装并启动 rng-tools 增加熵池
yum install -y rng-tools
systemctl start rngd
systemctl enable rngd
如为虚拟机或 CPU 不支持 DRNG,可编辑服务使用 /dev/urandom 作为熵源:
cp /usr/lib/systemd/system/rngd.service /etc/systemd/system
修改 ExecStart=/sbin/rngd -f -r /dev/urandom
systemctl daemon-reload && systemctl restart rngd
再次观察熵值与启动日志,通常可恢复正常。
三 JVM 与内存参数优化
- 在 catalina.sh 中设置合理的堆与 GC(示例为 4GB 内存的通用值,可按机器内存线性调整):
JAVA_OPTS=“$JAVA_OPTS -server -Xms4g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+PrintGCDetails -XX:+HeapDumpOnOutOfMemoryError”
要点:
- 将 -Xms 与 -Xmx 设为相同,避免运行期扩缩堆带来的抖动;
- 选择 G1GC(或根据负载选择并行 GC),并设置目标停顿;
- 打开 HeapDumpOnOutOfMemoryError 便于排障。
调整后重启,用 jstat -gc、jmap -heap 等工具验证参数生效与 GC 行为。
四 Tomcat 配置与服务优化
- 连接器与线程池(server.xml):优先使用 NIO,并按并发量调优线程与队列
说明:
- 禁用 DNS 反查(enableLookups=false)可避免启动时及运行期阻塞;
- 启用 HTTP 压缩 降低传输耗时(对启动期影响有限,但对首包体验有帮助);
- 可按需配置 APR(org.apache.coyote.http11.Http11AprProtocol)以获得更佳 I/O 性能(需安装 tomcat-native 与 APR 库)。
- 应用部署策略:减少启动期压力
说明:关闭不必要的 自动部署/热部署,按需手动部署,缩短初始化时间。
- 系统层面:适度提升文件描述符与内核网络参数(/etc/security/limits.conf、/etc/sysctl.conf),并视环境 禁用透明大页(echo never > /sys/kernel/mm/transparent_hugepage/enabled),以减少内核路径上的额外开销。
五 验证与回退
- 验证步骤:
- 重启 Tomcat 并 tail -f logs/catalina.out,确认不再出现 SecureRandom 长时间阻塞日志;
- 执行 cat /proc/sys/kernel/random/entropy_avail,熵值应明显回升(如 >1000);
- 使用 ps -ef | grep tomcat 获取进程号,jmap -heap 校验 Xms/Xmx 是否生效;必要时用 jstat -gc 观察 GC 停顿。
回退建议:若业务对密码学强随机性有严格要求,优先保留 /dev/random 并通过 rngd 增加熵;如仅为提升启动速度且合规允许,再采用 /dev/urandom 或 -Djava.security.egd 方案。