根本原因是jdk默认securerandom使用/dev/random阻塞等待熵池,导致tomcat启动卡在“initializing protocolhandler”;修复方案是将java.security中securerandom.source改为file:/dev/urandom或添加-djava.security.egd=file:/dev/./urandom参数。

为什么改了JAVA_HOME后Tomcat启动变慢
根本原因不是环境变量本身,而是JDK默认的随机数生成器卡在/dev/random上。Tomcat启动时(尤其是首次)会调用SecureRandom生成会话ID、SSL密钥等,而/dev/random依赖系统熵池,Linux服务器若无足够硬件中断(比如虚拟机、云主机常见),就会阻塞等待,导致启动耗时从几秒拉长到几十秒甚至更久。
- 现象:执行
./startup.sh后控制台长时间无输出,catalina.out里最后日志停在“Initializing ProtocolHandler”附近 - 验证方式:启动时加
-Djava.security.egd=file:/dev/./urandom参数,若明显变快,基本可锁定问题 - 不建议直接改
/dev/random软链接——会影响整个系统安全随机数行为
最快生效的修复方式:改JDK的java.security配置
这是最稳定、影响面最小的方案,无需重启服务器,改完即生效(下次Tomcat启动时读取)。
- 路径定位:
$JAVA_HOME/jre/lib/security/java.security(JDK 8/11/17 均适用) - 找到这一行:
securerandom.source=file:/dev/random - 改成:
securerandom.source=file:/dev/urandom - 注意:必须保留
file:前缀,不能写成/dev/urandom,否则JVM会忽略 - 修改后无需重启JDK进程,Tomcat下次启动自动生效
替代方案:启动脚本中加JVM参数(适合临时验证或容器环境)
如果无法修改JDK全局配置(如共享JDK环境、权限受限),可在Tomcat启动时注入参数,效果等同于上面的配置,但优先级更高。
- Linux下编辑
$CATALINA_HOME/bin/catalina.sh,在if [ -z "$JAVA_OPTS" ] ; then之后追加:
JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"
catalina.bat,在set JAVA_OPTS=行后加:set JAVA_OPTS=%JAVA_OPTS% -Djava.security.egd=file:/dev/./urandom
/dev/./urandom而非/dev/urandom——这是JVM的一个绕过检查的兼容写法,避免部分JDK版本报错容易被忽略的细节:容器与云主机的特殊性
在Docker、Kubernetes或阿里云/腾讯云ECS上,这个问题更频繁,因为这些环境通常缺乏键盘、鼠标、磁盘IO等熵源。即使你改了java.security,如果镜像基础层没预装haveged或rng-tools,其他Java应用仍可能卡住。
- 容器内临时补救:
apt-get install -y haveged && systemctl start haveged(Debian/Ubuntu) - 生产镜像建议:构建时就写入
java.security修改,或固定使用-Djava.security.egd参数 - 别信“改
maxThreads就能解决启动慢”——那是处理请求阶段的参数,和启动阻塞无关











