今天生产环境出现一个诡异的现象,授权服务奇慢无比,其他接口确都正常,此现象只出现在生产环境,而我们开发,测试,预发,环境基本一致;,然后就开始了漫无边际的日志海洋里寻找原因,
017-05-10 14:00:57.951 DEBUG 20674 --- [ionManagerTimer] h.i.c.PoolingHttpClientConnectionManager : Closing expired connections
2017-05-10 14:01:01.604 INFO 20674 --- [nio-8211-exec-6] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [31,896] milliseconds.
2017-05-10 14:01:01.618 DEBUG 20674 --- [nio-8211-exec-6] o.s.b.f.s.DefaultListableBeanFactory : Creating instance of bean 'scopedTarget.oauth2ClientContext'
2017-05-10 14:01:01.618 DEBUG 20674 --- [nio-8211-exec-6] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.cache.config.internalCacheAdvisor'
2017-05-10 14:01:01.618 DEBUG 20674 --- [nio-8211-exec-6] o.s.b.f.s.DefaultListableBeanFactory : Returning cached instance of singleton bean 'org.springframework.retry.annotation.RetryConfiguration'
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产生大量随机数的速度要慢。
解决办法:
java -jar app.jar -Djava.security.egd=file:/dev/./urandom