并发不高的程序长时间未使用后登录为什么会变得很慢

现象

一些内部管理系统,Java的程序部署到服务器之后,由于并发不高,晚上没人使用,第2天或者周一早上开始使用的人会登录特别缓慢。

分析

反复检查程序都没有发现问题,主要一开始怀疑IO的问题,因为内存中的一般不会出现超时的。但是没发现IO问题,却在无意间在上看到了一下提示。

2020-07-25 11:08:50 - [WARN ] [http-nio-8092-exec-10] o.a.c.util.SessionIdGeneratorBase    : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [28,190] milliseconds.
2020-07-25 11:08:50 - [WARN ] [http-nio-8092-exec-6] o.a.c.util.SessionIdGeneratorBase    : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [65,102] milliseconds.
2020-07-25 11:08:50 - [WARN ] [http-nio-8092-exec-2] o.a.c.util.SessionIdGeneratorBase    : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [166,254] milliseconds.

从日志可以看出,SessionIdGeneratorBase这个类要创建一个SecureRandom用于生成sessionID,居然用了几十秒到一百多秒不等的时间。

原因

原因是Tomcat在产生session ID时的SHA1PRANG算法使用了jre的SecureRandom。SHA1PRNG 算法是基于 SHA-1 算法实现且保密性较强的伪随机数生成器。而SHA1PRNG的种子产生器,是通过读取$JAVA_HOME/jre/lib/security/java.security 这个文件获取的,配置项为securerandom.source。

以下是java.security的配置片段:

# "file:/dev/urandom" will enable the native Microsoft CryptoAPI seeding
# mechanism for SHA1PRNG.
#
# By default, an attempt is made to use the entropy gathering device
# specified by the "securerandom.source" Security property.  If an
# exception occurs while accessing the specified URL:
#
#     SHA1PRNG:
#         the traditional system/thread activity algorithm will be used.
#
#     NativePRNG:
#         a default value of /dev/random will be used.  If neither
#         are available, the implementation will be disabled.
#         "file" is the only currently supported protocol type.
#
# The entropy gathering device can also be specified with the System
# property "java.security.egd". For example:
#
#   % java -Djava.security.egd=file:/dev/random MainClass
#
# Specifying this System property will override the
# "securerandom.source" Security property.
#
# In addition, if "file:/dev/random" or "file:/dev/urandom" is
# specified, the "NativePRNG" implementation will be more preferred than
# SHA1PRNG in the Sun provider.
#
securerandom.source=file:/dev/random

这个/dev/random被称为收集环境噪音的熵收集装置(也叫熵池The entropy gathering device),系统将当前运行的随机状态写入其中,作为伪随机数的种子。/dev/random非常适合那些需要非常高质量随机性的场景,比如一次性的支付或生成密钥的场景。但random有个特点就是阻塞式的,直到熵池收集到足够的环境噪声数据。由于长时间无人使用系统,就会导致熵池变空,从而无法产生随机数。我们看到这个配置的注释里也提到了另外一个文件,那就是/dev/urandom。它和/dev/random的区别就是,urandom是ublock的。

因此,由于无法产生随机数,jvm就阻塞住了,直至有足够的环境噪音,这样子随机数的随机行当然是高了很多,但也给系统带来了问题。可以将

securerandom.source=file:/dev/random

改为

securerandom.source=file:/dev/./urandom

为什么会多了个./呢,据说这是jvm的一个bug,有人反馈即使对 securerandom.source 设置为 /dev/urandom 它也仍然使用的 /dev/random。所以使用/dev/./urandom 这样的变通方法。也有人评论说这个不是 bug,是有意为之。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值