spring boot 程序启动缓慢的问题

https://blog.csdn.net/yt4766269/article/details/78439811

今天发现一台服务器上的springboot程序启动特别慢,完全启动起来用了有好几分钟。刚开始以为是代码写的有问题造成了卡死,直到看到这条log:

  1. 2017-03-08 10:06:49.600 INFO 6439 --- [main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8888 (http)

  2. 2017-03-08 10:06:49.613 INFO 6439 --- [main] o.apache.catalina.core.StandardService : Starting service Tomcat

  3. 2017-03-08 10:06:49.614 INFO 6439 --- [main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.37

  4. ......

  5. 2017-03-08 10:09:10.167 INFO 6439 --- [ost-startStop-1] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [140,108] milliseconds.

原来是tomcat的启动耗费了140多秒。而罪魁祸首是这个SecureRandom类。

其实,这个问题我之前就有耳闻,但从没遇到过,也就没太在意。今天终于让我遇上了,墨菲定律又生生应验了一回。。


tomcat的文档里有个概念叫Entropy Source(熵源)

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.:

<DATE> org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [5172] milliseconds.

意思是tomcat7以上的版本,在启动时会调用SecureRandom类来生成随机数。如果用于初始化SecureRandom熵源是个短熵(熵不够用),那么就会报文章开头说的warning了。


jdk的配置文件中,使用securerandom.source设置了熵源:

 
  1. cat /usr/java/jdk1.8.0_121/jre/lib/security/java.security

  2.  
  3. securerandom.source=file:/dev/random

可以看到默认值是:/dev/random
所以程序启动后SecureRandom类会读取/dev/random以获取随机序列,这是一个同步操作。当熵池(entropy pool) 中没有足够的熵时,读取/dev/random就会造成阻塞,直到收集到了足够的熵,程序才会继续往下进行。
(关于什么是/dev/random,可以查看 wiki的介绍


解决方法是修改成非阻塞的熵源/dev/urandom
可以修改java.security文件中的securerandom.source值,也可以使用参数java.security.egd

java -jar app.jar -Djava.security.egd=file:/dev/./urandom

至于为什么是/dev/./urandom,而不是/dev/urandom,这源于java的一个bug。大意是/dev/urandom在某些情况下可能还是最终会转换成调用/dev/random。所以为了保险起见,还是使用/dev/./urandom吧!

猜你喜欢

转载自blog.csdn.net/caodongfang126/article/details/83029488