CentOS 7 下Tomcat啟動超慢的原因及解決方案
現象
CentOS 7系統中安裝好openjdk和Tomcat後,啟動過程很慢,長達數分鐘,日誌如下:
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執行到這裡時出問題了,google了一下,經過一番搜尋明白了其中的緣由。
原因
在tomcat官方wiki文件的HowToFasterStartUp章節中,Entropy Source部分有一段這樣的說明:
Tomcat 7+嚴重依賴SecureRandom類為其sessionID和其他地方提供隨機值。如果用於初始化SecureRandom的熵源缺少熵,則可能會在啟動期間導致延遲,具體取決於您的JRE。發生這種情況時,您會在日誌中看到警告,例如:
<DATE> org.apache.catalina.util.SessionIdGenerator createSecureRandom INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [5172] milliseconds.
有一種方法可以通過設定以下系統屬性來配置JRE以使用非阻塞熵源:
-Djava.security.egd = file:/dev/./urandom
另請注意,使用非阻塞源替換阻塞熵源實際上會降低安全性,因為您獲得的隨機資料較少。
從這裡我們得知Tocmat的Session ID是通過SHA1PRNG演算法計算得到的,計算Session ID的時候必須有一個金鑰,為了提高安全性Tomcat在啟動的時候會通過隨機生成一個金鑰,它強依賴於獲取熵池中的隨機數來進行建立。
那麼什麼是/dev/random?什麼是熵池?
/dev/random
從維基百科得知,在UNIX作業系統(包括類UNIX系統)中,/dev/random
是一個特殊的裝置檔案,可以用作隨機數生成器或偽隨機數生成器。
Linux核心中的是第一個以背景噪聲
產生真正的隨機數產生的實現,它允許程式訪問來自裝置驅動程式或其它來源的背景噪聲。
Linux上有兩個通用的隨機裝置:/dev/random
和/dev/urandom
。其中/dev/random
的隨機性最好,因為它是一個阻塞的裝置。而/dev/random
的一個副本是/dev/urandom
(“unblocked”,非阻塞的隨機數生成器),它會重複使用熵池中的資料以產生偽隨機資料。這表示對/dev/urandom
的讀取操作不會產生阻塞,但其輸出的熵可能小於/dev/random
的。所以它可以作為生成較低強度密碼的偽隨機數生成器,不建議用於生成高強度長期密碼。
熵池
熵池本質上是若干位元組,/proc/sys/kernel/random/entropy_avail
中儲存了熵池現在的大小,/proc/sys/kernel/random/poolsize
是熵池的最大容量,單位都是bit。如果entropy_avail
的值小於要產生的隨機數bit數,那麼/dev/random
就會堵塞。
為什麼熵池不夠用?
熵池實際上是從各種noice source中獲取資料,noice source可能是鍵盤事件、滑鼠事件、裝置時鐘中等。linux核心從2.4升級到2.6時,處於安全性的考慮,廢棄了一些source。source減少了,熵池補給的速度當然也變慢,進而不夠用。
其實,通過消耗熵池,可以構造DDOS攻擊。原理很簡單,熵池空了,依賴隨機數的業務(SSL,加密等)就不能正常進行。
通過以上資訊,筆者得知該問題是由於熵池不足導致的。怎麼解決?
解決方案
方法一、降低熵生成的隨機性要求
使用非阻塞性的生成器/dev/urandom
代替/dev/random
。
1、可在JVM環境中配置
通過配置發生器指定熵收集守護程式
修改$JAVA_PATH/jre/lib/security/java.security
中引數securerandom.source
為:
securerandom.source=file:/dev/./urandom
2、也可在Tomcat環境中配置
通過配置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
這個系統屬性egd表示熵收集守護程式(entropy gathering daemon)。
方法二、使用熵生成器補充熵池(推薦)
1、[硬體隨機數生成器]安裝並使用rng-tools作為額外的熵隨機數生成器(推薦)
# 安裝rng-tools
yum install rng-tools -y
# 測試rngd
rngd -f
# 啟動rngd
systemctl start rngd
# 設定自啟動
systemctl enable rngd
# 檢視自啟動列表
systemctl list-unit-files
cat /dev/random
命令會消耗熵池,rngd
守護程式會補充熵池,可使用如下命令來測試隨機數生成的情況:
cat /dev/random | rngtest -c 100
# 測試結果
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、[軟體隨機數生成器]在rng-tools仍不滿足的情況下,可使用haveged作為額外的熵隨機數生成器
haveged專案的目的是提供一個簡單易用的不可預測隨機數生成器,基於HAVEGE演算法。Haveged可以解決在某些情況下,系統熵過低的問題。此程式無法保證熵的質量,如果對安全要求較高,請考慮使用硬體隨機數生成器rng-tools。
要檢查是否需要 Haveged,可使用下面命令檢視當前收集到的熵:
cat /proc/sys/kernel/random/entropy_avail
如果結果比較低 (<1000),建議安裝 haveged,否則加密程式會處於等待狀態,直到系統有足夠的熵。
# 安裝haveged
yum install haveged -y
# 啟動haveged
systemctl start haveged
# 設定自啟動
systemctl enable haveged
安裝 haveged 之後,可以再次檢視系統熵看下有無提升。
因為方法一存在一定的不安全性,且需要對環境進行配置,為了滿足熵的需要,這裡筆者選擇了第二種方法,使用rng-tools作為額外的熵隨機數生成器,同以上操作後順利解決了問題。
操作後重啟tomcat日誌如下,啟動速度快了兩個數量級:
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
相關文章
- GitHub下載慢的原因及解決方法Github
- APP執行緩慢5個原因及解決方案APP
- CentOS 7 SSH 連線超時自動斷開解決方案CentOS
- centos7 設定tomcat自啟動CentOSTomcat
- CentOS7中啟動Tomcat後,8080埠不能被外部訪問的解決辦法。CentOSTomcat
- 調節閥振動原因分析及解決方案
- 造成黏包的原因,及解決方案
- centos7網路卡啟動不了的解決辦法CentOS
- 解決weblogic啟動慢和建立域慢的方法Web
- 解決方案集錦——Tomcat伺服器啟動失敗Tomcat伺服器
- tomcat無法啟動的解決方法Tomcat
- 伺服器自動重啟的原因及解決方法-VeCloud伺服器Cloud
- 移動APP啟動慢解決實踐APP
- Mac 下 Docker 執行較慢的原因分析及個人見解MacDocker
- nodejs埠被佔用原因及解決方案NodeJS
- SpringBoot整合Redis亂碼原因及解決方案Spring BootRedis
- CentOS 7下yum安裝Apache及不解析php問題的解決CentOSApachePHP
- mysql同步(複製)延遲的原因及解決方案MySql
- CentOS 7 yum 無法下載的解決方法CentOS
- No bean named 'xxx' is defined錯誤,原因及解決方案Bean
- Handler記憶體洩漏原因及解決方案記憶體
- 家庭電氣火災原因分析及解決方案
- spring.jackson.date-format失效原因及解決方案SpringORM
- CentOS 7 "線纜被拔出"的原因和解決方法CentOS
- Mysql 非同步複製延遲的原因及解決方案MySql非同步
- JS定時器不可靠的原因及解決方案JS定時器
- 學習記錄:MySQL碎片化的原因及解決方案?MySql
- 啟動tomcat中的startup.bat閃退原因TomcatBAT
- CentOS 7 命令 lsb_release: command not found 解決方案CentOS
- windows10系統下EXE程式啟動慢怎麼解決Windows
- centos7 boot空間不夠用的解決方案CentOSboot
- Tomcat 7&8 熵池阻塞變慢詳解Tomcat熵
- tomcat 啟動dangdang的spring配置超時TomcatSpring
- Tomcat 7 啟動分析(三)Digester 的使用Tomcat
- 網站開啟的速度慢原因都什麼可以這麼解決網站
- 跨域的原因以及解決方案跨域
- SQL Server查詢慢的解決方案SQLServer
- 解決centos 7 安裝、檢查和配置源為aliyun解決方案CentOS