OpenJDK下SpringBoot使用HttpSession時頁面打開卡住

近期將一個老項目向ARM版的CentOS7移植時,遇到了SpringBoot啓動順利,但訪問頁面卡住的問題。因爲是aarch64架構,所以使用了openjdk,這個項目以前在x86_64環境下一直是用Oracle的ServerJRE,沒有遇到問題。這次啓動正常,但啓動完成後,訪問部分頁面正常,部分頁面會卡住,卡住的時間不固定,有時長有時短,毫無規律可言。並且當卡住的頁面正常後,再刷新不會再次卡住。
java


第一想法確定是查日誌,在首次訪問卡頓頁面時,Spring框架有一條這樣的WARN:算法


2019-12-09 17:40:32.995  WARN 15161 --- [https-jsse-nio-443-exec-8] o.a.c.util.SessionIdGeneratorBase        :
 Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [178,241] milliseconds.


爲Session建立SecureRandom實例耗時將近3分鐘,這就是頁面卡住的緣由,同時也解釋了爲何只有部分頁面卡住,由於不是全部頁面都使用了Session,同時也解析了爲何卡住的頁面可訪問後再刷新就正常了,由於建立SecureRandom instance只進行一次。
apache


翻回來看看緣由,項目中使用了Tomcat Embed做爲內嵌WEB服務器,而Tomcat在生成session ID時會使用org.apache.catalina.util.SessionIdGeneratorBase來產生安全隨機類SecureRandom實例。爲了算法保密性較強,須要用到僞隨機數生成器,Tomcat用到的是SHA1PRNG算法,爲了獲得隨機種子,在Linux中,通常從/dev/random或/dev/urandom中產生,二者原理都是利用系統的環境噪聲產生必定數量的隨機比特,區別在於系統環境噪聲不夠時,random會阻塞,而urandom會犧牲安全性避免阻塞。安全


從卡頓現象上看,必定是用了/dev/random致使的,看一下$JAVA_HOME/jre/lib/security/java.security文件,找到下面的內容:bash


#
# Sun Provider SecureRandom seed source.
#
# Select the primary source of seed data for the "SHA1PRNG" and
# "NativePRNG" SecureRandom implementations in the "Sun" provider.
# (Other SecureRandom implementations might also use this property.)
#
# On Unix-like systems (for example, Solaris/Linux/MacOS), the
# "NativePRNG" and "SHA1PRNG" implementations obtains seed data from
# special device files such as file:/dev/random.
#
# On Windows systems, specifying the URLs "file:/dev/random" or
# "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,按照上面的註釋部分,解決方案也不復雜,能夠添加啓動參數或者修改java.security:
服務器


解決方法1:session

啓動參數添加-Djava.security.egd=file:/dev/urandom,如:架構

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


解決方法2:
框架

修改$JAVA_HOME/jre/lib/security/java.security,找到securerandom.source並修改:dom

securerandom.source=file:/dev/urandom



再重啓站點,卡頓現象消失。

相關文章
相關標籤/搜索