? 上一篇下一篇 ?

徹底解決Tomcat啟動速度慢的問題,只需一行代碼原來這么簡單

  我們在服務器上啟動tomcat的時候,偶爾會碰到tomcat啟動起來特別慢,甚至是卡死在某一步的情況,這篇文章主要介紹了快速解決Tomcat啟動慢的問題,超簡單!具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧今天在幫一位同學解決了一個問題——Tomcat啟動超級慢,大概五六分鐘。解決之后,只需要3秒鐘即可啟動。
 
問題怎么解決呢?
 
在Tomcat的bin目錄下找到catalina.sh,然后打開它,在以下位置添加一行代碼:
 

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


2019年02月12日補充:很多朋友想知道原理,我就簡單說明一下。
 
Tomcat 7和Tomcat 8在啟動的時候會調用org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom來產生一串安全隨機數。
 
在Linux(CentOS)環境下,隨機數可以從兩個特殊的文件中產生,一個是/dev/urandom,另外一個是/dev/random。
 
它們產生隨機數的原理是利用當前系統的熵池來計算出固定一定數量的隨機比特,然后將這些比特作為字節流返回。熵池就是當前系統的環境噪音,熵指的是一個系統的混亂程度,系統噪音可以通過很多參數來評估,如內存的使用,文件的使用量,不同類型的進程數量等等。
 
/dev/random在不能產生新的隨機數時會阻塞程序,直到根據熵池產生新的隨機字節之后才返回;而/dev/urandom不會(ublock),當然,產生的隨機數效果也不太好。
 
所以我們強制Tomcat使用/dev/urandom而不是/dev/random來產生隨機數,速度就會大幅提升——由好幾分鐘到只有幾秒鐘。
 
補充知識:Tomcat 啟動很慢,且日志上無任何錯誤的解決方案
 
1.問題
 
有一次把項目部署上去阿里云的時候,項目沒有問題,但是啟動tomcat的時候,啟動到一半,半天才有反應,才執行完tomcat的啟動進程。
 
Tomcat 啟動很慢,且日志上無任何錯誤,在日志中查看到如下信息:
 

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 se
 
2.原因
 
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的讀操作將被阻塞,直到熵池收集到足夠的環境噪聲數據。這么做的目的是成為一個密碼安全的偽隨機數發生器,熵池要有盡可能大的輸出。對于生成高質量的加密密鑰或者是需要長期保護的場景,一定要這么做。
 
3.解決方案
 
有兩種解決辦法:
 
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這個文件。
 
可以通過在vi命令進行查找:
 

?securerandom.source
 
找到下面的內容:
 

securerandom.source=file:/dev/random
 
然后替換成:
 

securerandom.source=file:/dev/./urandom
 


  熵池不僅僅Tomcat用,Linux下的所有應用程序產生隨機數都會用到這個,所以不僅僅是Tomcat可能被阻塞。如果你搜索會發現Apache、Nginx、OpenSSL都被這個問題坑過。如果我們通過修改Java的配置來解決這個問題其實只是解決Java應用程序的問題,只能是治標不治本。根治的方法應該是通過rngd提高隨機數生成的速度。

總結
   經驗不是經歷。用別人的經驗解決一個問題不難,難的是自己從頭走一遍這條路,更加難的是推翻前人的經驗對一個問題能夠有自己的看法和領悟。

這個案例加深了我對strace的理解,對于空中加油這種類型的系統調試有了自己的經驗;通過對原因的深入分析我找到了更好的辦法。