Spring Boot启动第一次访问慢Creation of SecureRandom Instance is Slow in Spring Boot
Spring Boot启动第一次访问慢Creation of SecureRandom Instance is Slow in Spring Boot
Linux服务器上启动了一个Spring Boot项目后,第一次请求用了很长的时间,查看日志后发现一个关键内容:Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [155,058] milliseconds.
2020-11-18 14:49:57.096 INFO 29140 --- [nio-8181-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 18 ms 2020-11-18 14:52:12.835 WARN 29140 --- [nio-8181-exec-1] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [135,666] milliseconds. 2020-11-18 14:52:12.843 WARN 29140 --- [nio-8181-exec-4] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [112,500] milliseconds. 2020-11-18 14:52:12.844 WARN 29140 --- [nio-8181-exec-6] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [21,618] milliseconds. 2020-11-18 14:52:12.844 WARN 29140 --- [nio-8181-exec-3] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [45,144] milliseconds. 2020-11-18 14:52:12.844 WARN 29140 --- [nio-8181-exec-2] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [47,941] milliseconds. 2020-11-18 14:52:12.844 WARN 29140 --- [nio-8181-exec-7] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [49,850] milliseconds. 2020-11-18 14:52:12.844 WARN 29140 --- [nio-8181-exec-8] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [82,910] milliseconds. 2020-11-18 14:52:12.844 WARN 29140 --- [nio-8181-exec-9] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [109,737] milliseconds.
原因分析
从日志的内容我们基本可以知道,是服务接收到第一个请求时,需要为当前会话创建一个Session ID。而创建这个Session ID需要用到 java.security.SecureRandom
这个类来生成一个随机数。就是创建这个类的实例消耗了很长的时间。在类UNIX的系统上,SecureRandom
会默认使用 /dev/random
文件来获取随机数,通过该文件获取随机数是可能会阻塞的。具体内容可参考维基百科:https://en.wikipedia.org/wiki//dev/random。
除了 /dev/random
文件,其实还可以通过另一个文件 /dev/urandom
来获取随机数,两者最主要的一个区别就是通过 /dev/urandom
文件来获取随机数是不会阻塞的。
解决办法
查明原因后,我们就可以通过以下办法来解决这个问题,我们只需要在启动Spring Boot项目时通过命令行指定获取随机数的文件为 /dev/urandom
即可:
java -jar -Djava.security.egd=file:/dev/./urandom project.jar
-------------已经触及底线 感谢您的阅读-------------