最近項目上線部署的時候,發現一個問題。Tomcat在啓動過程當中耗費了很長的時間。查看日誌,發現耗時最長的地方是:
INFO [localhost-startStop-1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID gener
ation using [SHA1PRNG] took [1,693,533] milliseconds.
在網上查找資料後肯定,該問題是因爲tomcat的session id的生成主要經過java.security.SecureRandom生成隨機數來實現,隨機數算法使用的是」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的。它
能夠做爲生成較低強度密碼的僞隨機數生成器,不建議用於生成高強度長期密碼。
在tomcat的文檔裏的建議,採用非阻塞的熵源(entropy source),經過java系統屬性來設置:
-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 才行。也有人評論說這個不是bug,是有意爲之。java
個人最終解決方法以下:
找到 $JAVA_HOME/jre/lib/security/java.security 這個文件,找到裏面的
securerandom.source=file:/dev/random
或者
securerandom.source=file:/dev/urandom
修改成
securerandom.source=file:/dev/./urandom
原文詳情地址:http://www.roncoo.com/article/detail/125962linux