問題描述
線上環境中很容易出現一個java應用啟動非常耗時的情況,在日志中可以發現是session引起的亂數問題導致的
o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [170,241] milliseconds.
分析
在Springboot程式中有內置的tomcat,在tomcat給的優化檔案中,有一項是關于亂數生成時,采用的“熵源”(entropy source)的策略,
他提到tomcat7的session id的生成主要通過java.security.SecureRandom生成亂數來實作,亂數演算法使用的是”SHA1PRNG”
private String secureRandomAlgorithm = "SHA1PRNG";
在sun/oracle的jdk里,這個演算法的提供者在底層依賴到作業系統提供的隨機資料,在linux上,與之相關的是/dev/random和/dev/urandom,區別為:
/dev/random是阻塞的發生器
在讀取時,/dev/random設備會回傳小于熵池噪聲總數的隨機位元組,/dev/random可生成高隨機性的公鑰或一次性密碼本,若熵池空了,對/dev/random的讀操作將會被阻塞,直到收集到了足夠的環境噪聲為止
而 /dev/urandom 則是一個非阻塞的發生器:
dev/random的一個副本是/dev/urandom (”unlocked”,非阻塞的亂數發生器),它會重復使用熵池中的資料以產生偽隨機資料,這表示對/dev/urandom的讀取操作不會產生阻塞,但其輸出的熵可能小于/dev/random的,它可以作為生成較低強度密碼的偽亂數生成器,不建議用于生成高強度長期密碼,
這也并不是說明/dev/urandom不是做高強度的偽亂數生成器,這個討論可以看這個討論:/dev/urandom 不得不說的故事
解決方法
方法一
在 jre/lib/security/java.security 這個檔案里面把
securerandom.source=file:/dev/random
改為
securerandom.source=file:/dev/./urandom
方法二
在啟動引數中添加以下系統屬性
-Djava.security.egd=file:/dev/./urandom
這個系統屬性egd表示熵收集守護行程(entropy gathering daemon),但這里值為何要在dev和random之間加一個點呢?是因為一個jdk的bug,在這個bug的連接里有人反饋及時對 securerandom.source 設定為 /dev/urandom 它也仍然使用的 /dev/random,有人提供了變通的解決方法,其中一個變通的做法是對securerandom.source設定為 /dev/./urandom 才行
多說一嘴
在Docker中如何添加系統引數呢
首先在build鏡像時 要使用ENTRYPOINT 舉個例子
FROM jdk:alpine-security8
WORKDIR /
#解決中文亂碼問題
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US:en
ENV LC_ALL en_US.UTF-8
ADD sms-server.jar sms-server.jar
ADD application.properties application.properties
ADD bootstrap.properties bootstrap.properties
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
##使用如下的命令 添加-e JAVA_OPT是不起作用的
#ENTRYPOINT ["java","-jar","sms-server.jar"]
##要使用這條命令才行
ENTRYPOINT java ${JAVA_OPTS} -jar sms-server.jar
然后在啟動命令中添加對應的-e引數就可以了 舉個例子
docker run --name sms-server-security \
## 如下即可
-e JAVA_OPTS='-Djava.security.egd=file:/dev/./urandom' \
-e spring.cloud.nacos.discovery.server-addr=192.169.1.82:8848 \
-e spring.cloud.nacos.config.server-addr=192.169.1.82:8848 \
-e spring.cloud.nacos.config.ext-config[0].data-id=sms-server-node1.properties \
-p 8070:8090 \
-v /opt/sms_server/log:/log \
-v /opt/sms_server/nacos:/root/nacos \
-d \
3a1c93c34756
參考
https://hongjiang.info/jvm-random-and-entropy-source/
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/240330.html
標籤:Java
上一篇:超大份執行緒池,干杯,兄弟!陸
