tomcat 启动慢之 SecureRandom 坑

电脑环境

  1. CentOS-7-x86_64-DVD-1908
  2. Tomcat 8
  3. jdk 1.8

不知道什么原因,突然发现 jenkins构建tomcat 一直失败 ,上服务器一看 , tomcat启动非常慢,要花5~6分钟,甚至更久 所以 时间没到就超时失败了。

经过查看日志,发现耗时在这里:是创建 session id 引起的随机数问题导致的:

org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of 
SecureRandom instance for session ID generation using [SHA1PRNG] took [253,251] milliseconds.

百度了下

/dev/urandom /dev/random
在不能产生新的随机数的情况下会阻塞程序 在不能产生新的随机数时不会阻塞程序,数据的随机性也不高

The random number generator gathers environmental noise from device drivers and other sources into an entropy pool. The generator also keeps an estimate of the number of bits of noise in the entropy pool. From this entropy pool random numbers are created.
随机数发生器将来自设备驱动程序和其他来源的环境噪声收集到一个熵池中。生成器还保持熵池中噪声位数的估计。根据该熵池,创建随机数 (熵指的是一个系统的混乱程度)。

JVM上的Random 与 entropy-generating

在apache-tomcat官方文档:如何让tomcat启动更快里面提到了一些启动时的优化项,其中一项是关于随机数生成时,采用的“熵源”(entropy source)的策略。

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.:
org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [5172] milliseconds.
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/./urandom
Note the “/./“ characters in the value. They are needed to work around known Oracle JRE bug #6202721. See also JDK Enhancement Proposal 123. It is known that implementation of SecureRandom was improved in Java 8 onwards.
Also 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”.

发生这种情况的根本原因是 Tomcat 7/8 都使用 org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom 类产生安全随机类 SecureRandom 的实例作为会话 ID。
SecureRandom实例的种子播种如下:

  1. 在Windows上,使用SeedGenerator.getSystemEntropy()以及Windows CryptGenRandom()函数
  2. 在linux上,使用SeedGenerator.getSystemEntropy()以及/ dev / random。请注意,如果无法使用足够的熵,则从/ dev / random的读取可能会阻塞,因此首次植入SecureRandom对象时,尝试初始化该对象的线程可能会挂起。

解决办法

  1. 在tomcat 环境中解决:

         可以通过配置 JRE 使用非阻塞的方式,在 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
    

参考:
How To Faster Start Up
Tomcat 启动时 SecureRandom 非常慢解决办法

发布了15 篇原创文章 · 获赞 0 · 访问量 401

猜你喜欢

转载自blog.csdn.net/u010020726/article/details/105234769