在开发过程中发现一个问题,就是项目中的tomcat服务器启动速度很不稳定,时快时慢,尤其是部署在虚拟机里面的时候,慢得令人发指,不过同项目组的其他人对这个问题好像没放在心上,自己抽了点时间专门了解了一下。
原因分析:
查看日志发现以下内容
Apr 07, 2017 4:48:48 PM org.apache.catalina.startup.TldConfig execute
INFO: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
Apr 07, 2017 4:54:30 PM org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [326,348] milliseconds.
Apr 07, 2017 4:54:30 PM org.apache.catalina.startup.HostConfig deployDescriptor
INFO: Deployment of configuration descriptor /tomcat/conf/Catalina/localhost/ROOT.xml has finished in 350,966 ms
…
Apr 07, 2017 4:54:41 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8443"]
Apr 07, 2017 4:54:41 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-443"]
Apr 07, 2017 4:54:41 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 362716 ms
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [326,348] milliseconds.
这部分内容说明了Tomcat启动过程中创建session ID共花费了326秒,而整个启动过程花费了362秒。大部分的时间都花在了创建session ID的过程当中。
Tomcat使用SecureRandom为session ID提供随机值,这个过程中有一个阻塞源/dev/random,当它没有足够的数据用来生成随机数的时候,就会发生阻塞,直到数据足够用来生成随机数。
用来生成随机数的数据跟系统运行过程中的噪声有关(如硬件设备发生中断的时间,用户点击鼠标的时间间隔等),这些数据是完全随机,事先无法预测的。用户对设备的一些操作可以增加这些数据。
Tomcat官网有一部分相关的描述:
Tomcat 7+ heavily relies on SecureRandom class to provide random
values for its session ids and in other places. Depending on your JRE
it can cause delays during startup if entropy source that is used to
initialize SecureRandom is short of entropy. You will see warning in
the logs when this happens, e.g.:
org.apache.catalina.util.SessionIdGenerator createSecureRandom INFO:
Creation of SecureRandom instance for session ID generation using
[SHA1PRNG] took [5172] milliseconds.
参考:https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source
解决方法:
1、对于物理服务器,目前部分CPU支持DRNG(随机数发生器),不会有该问题发生。
判断CPU支持DRNG:
执行cat /proc/cpuinfo | grep rdrand有数据显示
2、对于KVM的虚拟机,可以添加一个虚拟化的RNG设备来解决。
3、使用/dev/urandom替代/dev/random
在catalina.sh中追加一个JAVA_OPTS参数:-Djava.security.egd=file:/dev/urandom
,/dev/urandom是一个伪随机数生成设备,不会造成阻塞。但是会造成Tomcat安全性能的降低。因为其随机数是按照一定轨迹生成的。
There is a way to configure JRE to use a non-blocking entropy source
by setting the following system
property: -Djava.security.egd=file:/dev/urandomAlso note that replacing the blocking entropy source (/dev/random)
with a non-blocking one actually reduces security because you are
getting less- random data. If you have a problem generating entropy on
your server (which is common), consider looking into
entropy-generating hardware products such as EntropyKey.
参考:https://wiki.apache.org/tomcat/HowTo/FasterStartUp#Entropy_Source