tomcat —— 啟動慢問題優化
tomcat啟動資訊:Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [370,632] milliseconds.
一、問題來源:
在新的伺服器上搭建了新的後臺,環境:Linux + tomcat 7 + JDK1.8 。
部署tomca專案,發現啟動過程非常久,用時6分鐘左右,檢視 catalina.out 檔案,日誌資訊如下:
Oct 24, 2018 5:14:03 PM org.apache.catalina.util.SessionIdGenerator createSecureRandom INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [370,632] milliseconds. Oct 24, 2018 5:14:05 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-nio-58020"] Oct 24, 2018 5:14:05 PM org.apache.catalina.startup.Catalina start INFO: Server startup in 377732 ms
特別注意這條資訊:
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [370,632] milliseconds.
在正常啟動情況下,是不會有這條提示資訊的。
二、解決辦法:兩種
1、在 JVM 環境中解決 -- 修改JVM引數
開啟$JAVA_PATH/jre/lib/security/java.security這個檔案,找到下面的內容:
securerandom.source=file:/dev/random (在JDK1.8中是 /random )
securerandom.source=file:/dev/urandom (在JDK1.7中是 /urandom )
(都)修改為:
securerandom.source=file:/dev/./urandom
2、在Tomcat環境中解決 -- 配置JRE使用非阻塞 Entropy Source
在 catalina.sh 檔案中加入一行:-Djava.security.egd=file:/dev/./urandom
解決之後,tomcat啟動的日誌資訊如下:僅用時6秒多。
Oct 25, 2018 12:38:03 PM org.apache.coyote.AbstractProtocol start INFO: Starting ProtocolHandler ["http-nio-58020"] Oct 25, 2018 12:38:03 PM org.apache.catalina.startup.Catalina start INFO: Server startup in 6876 ms
三、問題根本原因分析
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [370,632] milliseconds.
Tomcat 7/8 都使用 org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom 類產生安全隨機類 SecureRandom 的例項作為會話 session ID ,使用 SHA1PRNG 演算法。
SHA1PRNG演算法是基於SHA-1演算法實現且保密性較強的偽隨機數生成器。在 SHA1PRNG 演算法中,有一個種子產生器,可以根據配置執行各種操作。
在Linux中隨機數可以從兩個特殊的檔案中產生:
1)/dev/random:阻塞隨機數產生器(locked)。反覆使用熵池中的資料來產生偽隨機數,當不能產生新的隨機數時,會阻塞,直到能產生新的隨機數才返回。因此隨機效果好。/random 非常適合那些需要非常高質量隨機性的場景,比如一次性的支付或生成金鑰的場景。
2)/dev/urandom:非阻塞的隨機數產生器(unlocked)。反覆使用熵池中的資料來產生偽隨機數,當不能產生新的隨機數時,不會阻塞。因此隨機數產生效果不太好。
兩者產生隨機數的原理都是利用當前系統的熵池來計算出固定一定數量的隨機位元,然後將這些位元作為位元組流返回。
什麼是熵池?
熵池(entropy pool)就是當前系統的環境噪音,熵指的是一個系統的混亂程度,系統噪音可以通過很多引數來評估,如記憶體的使用,檔案的使用量,不同型別的程序數量等等。如果當前環境噪音變化的不是很劇烈或者當前環境噪音很小,比如剛開機的時候,而當前需要大量的隨機位元,這時產生的隨機數的隨機效果就不太好。
為什麼 tomcat 啟動慢?
在JDK1.8中,/jre/lib/security/java.security 檔案中預設使用的是 /dev/random (阻塞)。隨機數產生器會評估熵池中的噪聲資料的數量,當熵池為空時,來自/dev/random的讀操作將被阻塞,直到熵池收集到足夠的環境噪聲資料,這個收集噪聲資料過程就要花一定的時間,即會被阻塞較長的時間,所以,tomcat 啟動慢。
修改為 /dev/./urandom(非阻塞)後,不會被阻塞,產生大量隨機數的速度就比 /dev/random 快得多,tomcat 啟動就快多了。