1、问题现象
tomcat启动时候,日志显示如下,生成sessionid耗费了72S,整个tomcat部署完成耗费95s,时间远超过预期:
May 22, 2019 4:07:37 PM org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [72,748] milliseconds.
INFO: Deployment of web application archive /data/log4x/apache-tomcat-7.0.61/webapps/log4x-web.war has finished in 95,374 ms
May 22, 2019 4:22:10 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8184"]
May 22, 2019 4:22:10 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8013"]
May 22, 2019 4:22:10 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 95684 ms
2、问题原因
tomcat使用org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom类产生安全随机类SecureRandom的实例作为会话ID
SHA1PRNG算法是基于SHA-1算法实现且保密性较强的伪随机数生成器。
在SHA1PRNG中,有一个种子产生器,它根据配置执行各种操作。
Linux中的随机数可以从两个特殊的文件中产生,一个是/dev/urandom.另外一个是/dev/random。他们产生随机数的原理是利用当前系统的熵池来计算出固定一定数量的随机比特,然后将这些比特作为字节流返回。熵池就是当前系统的环境噪音,熵指的是一个系统的混乱程度,系统噪音可以通过很多参数来评估,如内存的使用,文件的使用量,不同类型的进程数量等等。如果当前环境噪音变化的不是很剧烈或者当前环境噪音很小,比如刚开机的时候,而当前需要大量的随机比特,这时产生的随机数的随机效果就不是很好了。
这就是为什么会有/dev/urandom和/dev/random这两种不同的文件,后者在不能产生新的随机数时会阻塞程序,而前者不会(ublock),当然产生的随机数效果就不太好了,这对加密解密这样的应用来说就不是一种很好的选择。/dev/random会阻塞当前的程序,直到根据熵池产生新的随机字节之后才返回,所以使用/dev/random比使用/dev/urandom产生大量随机数的速度要慢。
3、问题解决
如上问题有两种解决办法:
1)在Tomcat环境中解决
可以通过配置JRE使用非阻塞的Entropy Source。
在catalina.sh中加入这么一行:-Djava.security.egd=file:/dev/./urandom 即可。
2)在JVM环境中解决
打开$JAVA_PATH/jre/lib/security/java.security这个文件,找到下面的内容:
securerandom.source=file:/dev/random
替换成
securerandom.source=file:/dev/urandom
4、效果验证
采用方法2,修改java.security文件配置securerandom.source=file:/dev/urandom。修改后重新部署tomcat.日志中显示未在createSecureRandom处阻塞,部署时间比修改前缩短了近74s.基本等于修改前createSecureRandom处阻塞的时间。
May 22, 2019 4:28:31 PM org.apache.catalina.startup.HostConfig deployWAR
INFO: Deployment of web application archive /data/log4x/apache-tomcat-7.0.61/webapps/log4x-web.war has finished in 21,614 ms
May 22, 2019 4:28:31 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8184"]
May 22, 2019 4:28:31 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8013"]
May 22, 2019 4:28:31 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 21820 ms