首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

騰訊雲Ubuntu服務器Tomcat訪問極慢根因分析與一鍵修復方案

     編輯:Java 綜合教學

現象描述

  • 環境:騰訊雲學生機 (1核2G) + Ubuntu 14.04/16.04 + Tomcat 8.0/8.5/9.0
  • 症狀:Tomcat啟動正常,端口8080監聽正常,安全組放行,但瀏覽器訪問https://IP:8080 長時間等待無響應,最終超時或極慢加載
  • 排查:telnet IP 8080 連通,curl -v 卡在Waiting for response,日志無報錯,CPU/內存正常

根因定位:JVM熵源阻塞

核心原因:Tomcat 8+ / JVM 在生成Session ID、SecureRandom等安全操作時,默認使用/dev/random作為熵源。雲服務器虛擬化環境熵池極度匱乏,導致/dev/random讀取阻塞,線程卡死在NativePRNG.nextBytes(),表現為Tomcat「假死」。

驗證命令

# 觀察熵池可用位數 (正常應 > 1000,雲服務器常 < 200)
cat /proc/sys/kernel/random/entropy_avail

# 模擬讀取阻塞 (會卡住)
head -c 10 /dev/random

# 非阻塞對比 (瞬間返回)
head -c 10 /dev/urandom

三種修復方案:按推薦度排序

方案一:JVM啟動參數指定非阻塞熵源 (推薦,最小侵入)

# 編輯 Tomcat 啟動腳本
vim bin/catalina.sh

# 在 JAVA_OPTS 追加 (建議放在文件開頭 JAVA_OPTS 定義處)
JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"

關鍵細節:/dev/./urandom 而非 /dev/urandom。JDK有邏輯檢測路徑是否為/dev/urandom字面量,加/./繞過檢測,強制使用非阻塞源。

方案二:系統級安裝 haveged 熵補充守護進程 (治本)

# Ubuntu/Debian
apt-get update && apt-get install -y haveged
systemctl enable haveged && systemctl start haveged

# CentOS/RHEL
yum install -y haveged
systemctl enable haveged && systemctl start haveged

# 驗證熵池恢復
watch -n 1 cat /proc/sys/kernel/random/entropy_avail
# 應穩定在 3000+ 

原理:haveged利用CPU時鐘抖動持續補充熵池,讓/dev/random不再阻塞,全局生效 (JVM、SSH、GPG、OpenSSL等均受益)。

方案三:修改 JRE 安全配置文件 (永久、全局)

# 定位 java.security 文件
# Ubuntu: /usr/lib/jvm/java-8-openjdk-amd64/jre/lib/security/java.security
# 或: $JAVA_HOME/jre/lib/security/java.security

# 修改 securerandom.source
# 原: securerandom.source=file:/dev/random
# 新:
securerandom.source=file:/dev/urandom
# 或 (JDK 8u121+ 支持)
securerandom.strongAlgorithms=NativePRNGNonBlocking:SUN

驗證修復效果

# 1. 重啟 Tomcat
bin/shutdown.sh && bin/startup.sh

# 2. 觀察啟動日志關鍵字
# 修復前: "Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [xxx] milliseconds" (耗時數秒至數十秒)
# 修復後: 耗時 < 100ms

# 3. 瀏覽器訪問測試
curl -o /dev/null -s -w "HTTP: %{http_code}, Time: %{time_total}s\n" https://localhost:8080
# 應在 0.1-0.5s 內返回 200

深度原理:為什麼是 /dev/./urandom?

JDK 8u121+ 引入NativePRNGNonBlocking類,直接讀/dev/urandom。舊版本通過/dev/./urandom路徑技巧觸發同樣邏輯。

避坑指南:常見誤區

誤區後果正確做法
直接用 -Djava.security.egd=file:/dev/urandomJDK路徑匹配失效,仍走阻塞源必須用 file:/dev/./urandom
以為是Tomcat/網絡/防火牆問題走彎路檢查端口、安全組、連接數優先檢查熵池 cat /proc/sys/kernel/random/entropy_avail
生產環境不敢用 urandom 擔心安全性長期阻塞導致服務不可用現代Linux內核urandom已足夠安全 (CSPRNG);關鍵業務可配合haveged
只改Tomcat不改系統,遷移環境失效換服務器/容器化部署又慢基礎鏡像預裝haveged,或Dockerfile加入RUN apt-get install -y haveged

容器化部署最佳實踐 (Dockerfile)

FROM openjdk:8-jre-slim

# 安裝 haveged 解決熵源不足
RUN apt-get update && apt-get install -y haveged && rm -rf /var/lib/apt/lists/*
RUN systemctl enable haveged  # 若基礎鏡像支持systemd

# 或 直接設置 JVM 參數 (無需haveged)
ENV JAVA_OPTS="-Djava.security.egd=file:/dev/./urandom"

# 應用部署
COPY target/app.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app.jar"]

總結

雲服務器Tomcat訪問極慢 90% 為 JVM熵源阻塞。一行參數 -Djava.security.egd=file:/dev/./urandom 即可秒級修復;生產環境建議基礎鏡像預裝 haveged 徹底根治。排查路徑:entropy_avail 低 → 確認阻塞 → 加參數/裝haveged → 驗證啟動耗時與訪問響應。將此納入服務器初始化清單,杜絕重複踩坑。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved