1. 程式人生 > >【問題記錄】JAVA程序啟動大概率卡住6分鐘左右,應用日誌沒有任何WARN ERROR,系統日誌也沒有發現和程序相關日誌,最後定位TOMCAT SHA1PRNG耗時太長

【問題記錄】JAVA程序啟動大概率卡住6分鐘左右,應用日誌沒有任何WARN ERROR,系統日誌也沒有發現和程序相關日誌,最後定位TOMCAT SHA1PRNG耗時太長

系統是基於springboot開發的系統,java -jar啟動過程中發現經常會卡住6分鐘左右,才能啟動完成,全程沒有發現任何WANR和ERROR級別的日誌(其實早看看DEBUG和INFO日誌,可能問題早就解決了,慣性思維害人啊),再去檢視/var/log/message系統日誌,也沒發現任何和該程序相關的系統日誌;

無奈,初步懷疑伺服器虛擬機器有問題,讓運維排查下,也沒發現任何異常;

將同樣的jar包程式放到其它虛擬機器上跑,也有卡頓,但是10秒,20秒的樣子就結束了,雖然快了,但是也有卡頓,同樣的排查還是沒發現問題;

最後反覆啟停,反覆檢視,也是巧合在日誌裡有了發現,

[18-12-19 21:01:13:222][INFO ][org.apache.catalina.util.SessionIdGeneratorBase][localhost-startStop-1]Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [99,677] milliseconds.

 

發現了意外,這裡耗時簡直了

最後的解決方案就是在JVM啟動引數里加上如下一串:

-Djava.security.egd=file:/dev/./urandom

在tomcat的wiki上也有解釋 https://wiki.apache.org/tomcat/HowTo/FasterStartUp#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.

 

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

 

在讀取時,/dev/random裝置會返回小於熵池噪聲總數的隨機位元組。
/dev/random可生成高隨機性的公鑰或一次性密碼本。
若熵池空了,對/dev/random的讀操作將會被阻塞,直到收集到了足夠的環境噪聲為止

/dev/urandom則是一個非阻塞的發生器:

dev/random的一個副本是/dev/urandom (”unlocked”,非阻塞的隨機數發生器),它會重複使用熵池中的資料以產生偽隨機資料。
這表示對/dev/urandom的讀取操作不會產生阻塞,但其輸出的熵可能小於/dev/random的。
它可以作為生成較低強度密碼的偽隨機數生成器,不建議用於生成高強度長期密碼。

https://bugs.openjdk.java.net/browse/JDK-6202721

另外wiki裡也提到了為什麼linux核心裡的隨機數生成器採用SHA1雜湊演算法而非加密演算法,是為了避開法律風險(密碼出口限制)。

 

 

還有一篇文章專門解釋/dev/urandom

https://www.2uo.de/myths-about-urandom/

 

最後總結下:

其實還是虛擬機器的CPU差了點,跟其它環境的虛擬機器10秒,20秒的差了幾十倍,可見CPU差了很多啊。