CentOS 7 下Tomcat啟動超慢的原因及解決方案

現(xiàn)象

CentOS 7系統(tǒng)中安裝好openjdk和Tomcat后,啟動過程很慢,長達數(shù)分鐘,日志如下:

17:27:53.596 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.38
17:27:53.644 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/docs]
17:32:31.001 WARNING [localhost-startStop-1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [276,660] milliseconds.
17:32:31.022 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/docs] has finished in [277,378] ms
17:32:31.022 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/manager]
17:32:31.101 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/manager] has finished in [79] ms
17:32:31.101 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/examples]
17:32:31.509 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/examples] has finished in [408] ms
17:32:31.510 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/host-manager]
17:32:31.559 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/host-manager] has finished in [49] ms
17:32:31.559 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/ROOT]
17:32:31.576 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/ROOT] has finished in [17] ms
17:32:31.605 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
17:32:31.660 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
17:32:31.662 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 278084 ms

tomcat啟動耗時278084ms折合278秒,對于剛剛安裝的干凈tomcat,這肯定是不對勁的。
其中有一條日志引起了筆者的注意:

17:32:31.001 WARNING [localhost-startStop-1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [276,660] milliseconds.

顯然tomcat執(zhí)行到這里時出問題了,google了一下,經(jīng)過一番搜索明白了其中的緣由。

原因

在tomcat官方wiki文檔的HowToFasterStartUp章節(jié)中,Entropy Source部分有一段這樣的說明:

Tomcat 7+嚴重依賴SecureRandom類為其sessionID和其他地方提供隨機值。如果用于初始化SecureRandom的熵源缺少熵,則可能會在啟動期間導(dǎo)致延遲,具體取決于您的JRE。發(fā)生這種情況時,您會在日志中看到警告,例如:

<DATE> org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [5172] milliseconds.

有一種方法可以通過設(shè)置以下系統(tǒng)屬性來配置JRE以使用非阻塞熵源:

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

另請注意,使用非阻塞源替換阻塞熵源實際上會降低安全性,因為您獲得的隨機數(shù)據(jù)較少。

從這里我們得知Tocmat的Session ID是通過SHA1PRNG算法計算得到的,計算Session ID的時候必須有一個密鑰,為了提高安全性Tomcat在啟動的時候會通過隨機生成一個密鑰,它強依賴于獲取熵池中的隨機數(shù)來進行創(chuàng)建。
那么什么是/dev/random?什么是熵池?

/dev/random
從維基百科得知,在UNIX操作系統(tǒng)(包括類UNIX系統(tǒng))中,/dev/random是一個特殊的設(shè)備文件,可以用作隨機數(shù)生成器或偽隨機數(shù)生成器。
Linux內(nèi)核中的是第一個以背景噪聲產(chǎn)生真正的隨機數(shù)產(chǎn)生的實現(xiàn),它允許程序訪問來自設(shè)備驅(qū)動程序或其它來源的背景噪聲。
Linux上有兩個通用的隨機設(shè)備:/dev/random/dev/urandom。其中/dev/random的隨機性最好,因為它是一個阻塞的設(shè)備。而/dev/random的一個副本是/dev/urandom(“unblocked”,非阻塞的隨機數(shù)生成器),它會重復(fù)使用熵池中的數(shù)據(jù)以產(chǎn)生偽隨機數(shù)據(jù)。這表示對/dev/urandom的讀取操作不會產(chǎn)生阻塞,但其輸出的熵可能小于/dev/random的。所以它可以作為生成較低強度密碼的偽隨機數(shù)生成器,不建議用于生成高強度長期密碼。

熵池
熵池本質(zhì)上是若干字節(jié),/proc/sys/kernel/random/entropy_avail中存儲了熵池現(xiàn)在的大小,/proc/sys/kernel/random/poolsize是熵池的最大容量,單位都是bit。如果entropy_avail的值小于要產(chǎn)生的隨機數(shù)bit數(shù),那么/dev/random就會堵塞。

為什么熵池不夠用?

熵池實際上是從各種noice source中獲取數(shù)據(jù),noice source可能是鍵盤事件、鼠標事件、設(shè)備時鐘中等。linux內(nèi)核從2.4升級到2.6時,處于安全性的考慮,廢棄了一些source。source減少了,熵池補給的速度當然也變慢,進而不夠用。
其實,通過消耗熵池,可以構(gòu)造DDOS攻擊。原理很簡單,熵池空了,依賴隨機數(shù)的業(yè)務(wù)(SSL,加密等)就不能正常進行。

通過以上信息,筆者得知該問題是由于熵池不足導(dǎo)致的。怎么解決?

解決方案

方法一、降低熵生成的隨機性要求

使用非阻塞性的生成器/dev/urandom代替/dev/random

1、可在JVM環(huán)境中配置
通過配置發(fā)生器指定熵收集守護進程
修改$JAVA_PATH/jre/lib/security/java.security中參數(shù)securerandom.source為:

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

2、也可在Tomcat環(huán)境中配置
通過配置JRE使用非阻塞的Entropy Source獲取熵
$TOMCAT_HOME/bin/catalina.sh中加入:

if [[ "$JAVA_OPTS" != *-Djava.security.egd=* ]]; then
    JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"
fi

這個系統(tǒng)屬性egd表示熵收集守護進程(entropy gathering daemon)。

方法二、使用熵生成器補充熵池(推薦)

1、[硬件隨機數(shù)生成器]安裝并使用rng-tools作為額外的熵隨機數(shù)生成器(推薦)

# 安裝rng-tools
yum install rng-tools -y
# 測試rngd
rngd -f
# 啟動rngd
systemctl start rngd
# 設(shè)置自啟動
systemctl enable rngd
# 查看自啟動列表
systemctl list-unit-files

cat /dev/random命令會消耗熵池,rngd守護進程會補充熵池,可使用如下命令來測試隨機數(shù)生成的情況:

cat /dev/random | rngtest -c 100
# 測試結(jié)果
rngtest 6
Copyright (c) 2004 by Henrique de Moraes Holschuh
This is free software; see the source for copying conditions.  There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

rngtest: starting FIPS tests...
rngtest: bits received from input: 2000032
rngtest: FIPS 140-2 successes: 100
rngtest: FIPS 140-2 failures: 0
rngtest: FIPS 140-2(2001-10-10) Monobit: 0
rngtest: FIPS 140-2(2001-10-10) Poker: 0
rngtest: FIPS 140-2(2001-10-10) Runs: 0
rngtest: FIPS 140-2(2001-10-10) Long run: 0
rngtest: FIPS 140-2(2001-10-10) Continuous run: 0
rngtest: input channel speed: (min=13.823; avg=42.721; max=10761.019)Kibits/s
rngtest: FIPS tests speed: (min=93.041; avg=129.531; max=136.239)Mibits/s
rngtest: Program run time: 45733452 microseconds

2、[軟件隨機數(shù)生成器]在rng-tools仍不滿足的情況下,可使用haveged作為額外的熵隨機數(shù)生成器

haveged項目的目的是提供一個簡單易用的不可預(yù)測隨機數(shù)生成器,基于HAVEGE算法。Haveged可以解決在某些情況下,系統(tǒng)熵過低的問題。此程序無法保證熵的質(zhì)量,如果對安全要求較高,請考慮使用硬件隨機數(shù)生成器rng-tools。

要檢查是否需要 Haveged,可使用下面命令查看當前收集到的熵:

cat /proc/sys/kernel/random/entropy_avail

如果結(jié)果比較低 (<1000),建議安裝 haveged,否則加密程序會處于等待狀態(tài),直到系統(tǒng)有足夠的熵。

# 安裝haveged
yum install haveged -y
# 啟動haveged
systemctl start haveged
# 設(shè)置自啟動
systemctl enable haveged

安裝 haveged 之后,可以再次查看系統(tǒng)熵看下有無提升。


因為方法一存在一定的不安全性,且需要對環(huán)境進行配置,為了滿足熵的需要,這里筆者選擇了第二種方法,使用rng-tools作為額外的熵隨機數(shù)生成器,同以上操作后順利解決了問題。

操作后重啟tomcat日志如下,啟動速度快了兩個數(shù)量級:

17:58:07.068 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.38
17:58:07.088 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/docs]
17:58:07.740 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/docs] has finished in [652] ms
17:58:07.740 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/manager]
17:58:07.815 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/manager] has finished in [75] ms
17:58:07.816 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/examples]
17:58:08.241 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/examples] has finished in [425] ms
17:58:08.241 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/host-manager]
17:58:08.268 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/host-manager] has finished in [27] ms
17:58:08.269 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/opt/tomcat_8_5_38/webapps/ROOT]
17:58:08.306 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/opt/tomcat_8_5_38/webapps/ROOT] has finished in [37] ms
17:58:08.335 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
17:58:08.424 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
17:58:08.429 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 1411 ms

參考文檔:
https://stackoverflow.com/questions/40383430/tomcat-takes-too-much-time-to-start-java-securerandom
https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6202721
http://openjdk.java.net/jeps/123
https://zh.wikipedia.org/zh-hans//dev/random
https://wiki.apache.org/tomcat/HowTo/FasterStartUp
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/security_guide/sect-security_guide-encryption-using_the_random_number_generator
https://wiki.archlinux.org/index.php/Rng-tools
https://wiki.archlinux.org/index.php/Haveged
https://www.digitalocean.com/community/tutorials/how-to-setup-additional-entropy-for-cloud-servers-using-haveged

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 自己再阿里云申請了一臺1G1核的機器,每次重啟自己的服務(wù)tomcat都需要卡住很長時間,每次都是日志停在Root ...
    把愛放下會走更遠閱讀 26,855評論 9 16
  • 現(xiàn)象 最近新增了一批服務(wù)器,運維反饋說,部署的tomcat啟動很慢,但是沒有報任何異常,啟動后應(yīng)用也能正常運行。正...
    leoss_H閱讀 2,050評論 0 2
  • 最近項目上線部署的時候,發(fā)現(xiàn)一個問題。Tomcat在啟動過程中耗費了很長的時間。查看日志,發(fā)現(xiàn)耗時最長的地方是: ...
    倔強的小亮閱讀 5,136評論 0 3
  • 孩子八天偷偷花掉7000塊,父親暴打他,母親把視頻發(fā)到朋友圈。 這一個四分多鐘的視頻,在當?shù)睾芏嗳豪锉化倐鳌?事情...
    春下春樹閱讀 167評論 0 0
  • 一、家有男孩初長成兒子中專畢業(yè)后,不喜歡讀書,去外面打工兩年了,兩年的鍛煉,他知道沒有知識不行,沒有一定的文化水平...
    山茶聆聽閱讀 439評論 0 0

友情鏈接更多精彩內(nèi)容