通常情況下,tomcat啟動只要2~3秒鐘,突然有一天,tomcat啟動非常慢,要花5~6分鐘,查了很久,終於在這篇文章找到了解決方案,博主牛人啊。
原文參見:http://blog.csdn.net/chszs/article/details/49494701
Tomcat 8啟動很慢,且日誌上無任何錯誤,在日誌中檢視到如下資訊:
Log4j:[2015-10-29 15:47:11] INFO ReadProperty:172 - Loading properties file from class path resource [resources/jdbc.properties]
Log4j:[2015-10-29 15:47:11] INFO ReadProperty:172 - Loading properties file from class path resource [resources/common.properties]
29-Oct-2015 15:52:53.587 INFO [localhost-startStop-1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [342,445] milliseconds.
原因
Tomcat 7/8都使用org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom類產生安全隨機類SecureRandom的例項作為會話ID,這裡花去了342秒,也即接近6分鐘。
SHA1PRNG演算法是基於SHA-1演算法實現且保密性較強的偽隨機數生成器。
在SHA1PRNG中,有一個種子產生器,它根據配置執行各種操作。
1)如果Java.security.egd 屬性或securerandom.source屬性指定的是”file:/dev/random”或”file:/dev/urandom”,那麼JVM 會使用本地種子產生器NativeSeedGenerator,它會呼叫super()方法,即呼叫 SeedGenerator.URLSeedGenerator(/dev/random)方法進行初始化。
2)如果java.security.egd屬性或securerandom.source屬性指定的是其它已存在的URL,那麼會呼叫SeedGenerator.URLSeedGenerator(url)方法進行初始化。
這就是為什麼我們設定值為”file:///dev/urandom”或者值為”file:/./dev/random”都會起作用的原因。
在這個實現中,產生器會評估熵池(entropy pool)中的噪聲數量。隨機數是從熵池中進行建立的。當讀操作時,/dev/random裝置會只返回熵池中噪聲的隨機位元組。/dev/random非 常適合那些需要非常高質量隨機性的場景,比如一次性的支付或生成金鑰的場景。
當熵池為空時,來自/dev/random的讀操作將被阻塞,直到熵池收集到足夠的環境噪聲資料。這麼做的目的是成為一個密碼安全的偽隨機數發生器,熵池要有儘可能大的輸出。對於生成高質量的加密金鑰或者是需要長期保護的場景,一定要這麼做。
那麼什麼是環境噪聲?
隨機數產生器會手機來自裝置驅動器和其它源的環境噪聲資料,並放入熵池中。產生器會評估熵池中的噪聲資料的數量。當熵池為空時,這個噪聲資料的收集是比較花時間的。這就意味著,Tomcat在生產環境中使用熵池時,會被阻塞較長的時間。
解決
有兩種解決辦法:
1)在Tomcat環境中解決
可以透過配置JRE使用非阻塞的Entropy Source。
在catalina.sh中加入這麼一行:-Djava.security.egd=file:/dev/./urandom 即可。
加入後再啟動Tomcat,整個啟動耗時下降到Server startup in 2912 ms。
2)在JVM環境中解決
開啟$JAVA_PATH/jre/lib/security/java.security這個檔案,找到下面的內容:
securerandom.source=file:/dev/urandom
替換成
securerandom.source=file:/dev/./urandom