Tomcat在Linux下的性能調優技巧
Tomcat在Linux環境中的性能調優需從系統底層優化、Tomcat配置調整、JVM內存與垃圾回收優化、線程池優化及監控與持續改進五大維度綜合實施,以下是具體技巧:
Tomcat處理高并發連接時,可能因文件描述符(FD)數量不足導致請求被拒絕。需通過以下命令調整系統級FD限制:
# 查看當前FD限制
ulimit -n
# 臨時設置為65535(僅當前會話有效)
ulimit -n 65535
# 永久生效:編輯/etc/security/limits.conf,添加
* soft nofile 65535
* hard nofile 65535
調整TCP緩沖區大小和連接超時設置,提升網絡吞吐量與連接復用率:
# 編輯/etc/sysctl.conf,添加以下參數
net.ipv4.tcp_rmem = 4096 87380 16777216 # 接收緩沖區最小/默認/最大值(字節)
net.ipv4.tcp_wmem = 4096 87380 16777216 # 發送緩沖區最小/默認/最大值
net.ipv4.tcp_fin_timeout = 30 # TIME_WAIT狀態超時時間(秒)
net.ipv4.tcp_tw_reuse = 1 # 允許復用TIME_WAIT狀態的連接
net.core.rmem_max = 16777216 # 接收緩沖區最大值
net.core.wmem_max = 16777216 # 發送緩沖區最大值
# 應用配置
sysctl -p
降低vm.swappiness
(默認60)可減少系統使用交換空間的頻率,優先使用物理內存,提升I/O性能:
# 查看當前值
cat /proc/sys/vm/swappiness
# 臨時設置為10(0-100,值越低越傾向于使用物理內存)
echo 10 > /proc/sys/vm/swappiness
# 永久生效:編輯/etc/sysctl.conf
vm.swappiness = 10
優先使用NIO(非阻塞IO)或HTTP/2協議替代傳統HTTP/1.1,提升高并發下的吞吐量。在server.xml
中配置:
<!-- NIO連接器(Tomcat默認) -->
<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
<!-- HTTP/2協議(需Tomcat 9+,并配置SSL) -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
sslEnabled="true"
keystoreFile="/path/to/keystore.jks"
keystorePass="changeit"
maxThreads="200" />
調整maxThreads
(最大線程數)、minSpareThreads
(最小空閑線程數)、acceptCount
(排隊請求數)等參數,平衡并發處理能力與資源消耗:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxThreads="200" <!-- 最大線程數(根據CPU核心數調整,建議2*CPU核心數~4*CPU核心數) -->
minSpareThreads="50" <!-- 最小空閑線程數(避免頻繁創建線程) -->
maxSpareThreads="100" <!-- 最大空閑線程數(避免過多閑置線程消耗資源) -->
acceptCount="1000" <!-- 排隊請求數(當所有線程忙碌時,允許排隊的請求數,超過則拒絕) -->
enableLookups="false" <!-- 禁用DNS查詢(加快請求處理) -->
compression="on" <!-- 開啟GZIP壓縮(減少傳輸數據量) -->
compressionMinSize="1024"
compressableMimeType="text/html,text/xml,text/css,text/javascript,application/json" />
關閉Tomcat中不必要的功能,減少資源消耗:
server.xml
中的AJP Connector;web.xml
中添加<init-param><param-name>listings</param-name><param-value>false</param-value></init-param>
;根據應用內存需求調整JVM堆內存,避免頻繁GC。建議將-Xms
(初始堆)與-Xmx
(最大堆)設置為相同值,減少堆擴容帶來的性能波動:
# 編輯Tomcat的bin/catalina.sh(Linux)或bin/catalina.bat(Windows)
JAVA_OPTS="-Xms2G -Xmx2G" # 初始堆2GB,最大堆2GB(根據服務器物理內存調整,建議不超過物理內存的80%)
JAVA_OPTS="$JAVA_OPTS -XX:+UseG1GC" # 啟用G1GC
JAVA_OPTS="$JAVA_OPTS -XX:MaxGCPauseMillis=200" # 設置最大GC停頓時間(毫秒)
JAVA_OPTS="$JAVA_OPTS -XX:InitiatingHeapOccupancyPercent=45" # 觸發并發GC的堆占用率閾值
JDK 8及以上版本使用元空間(Metaspace)替代永久代(PermGen),需調整其大小以避免OutOfMemoryError: Metaspace
:
JAVA_OPTS="$JAVA_OPTS -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m"
通過Executor
元素定義自定義線程池,并在Connector
中引用,實現更靈活的線程管理:
<!-- 定義線程池 -->
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="500" <!-- 最大線程數(根據服務器硬件調整) -->
minSpareThreads="50" <!-- 最小空閑線程數 -->
maxIdleTime="60000" <!-- 線程空閑時間(毫秒,超過則銷毀) -->
prestartMinSpareThreads="true"/> <!-- 啟動時預創建最小空閑線程 -->
<!-- 在Connector中引用線程池 -->
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
通過JMX或VisualVM監控線程池的運行情況(如活躍線程數、隊列大小、拒絕請求數),根據監控結果調整maxThreads
和acceptCount
:
activeThreads
長期接近maxThreads
,說明線程池容量不足,需增加maxThreads
;queueSize
經常滿,說明隊列容量不足,需增加maxQueueSize
(默認無界,建議設置上限)。top
(查看CPU/內存使用率)、free -h
(查看內存使用情況)、netstat -tulnp | grep java
(查看網絡連接);使用壓力測試工具(如ab
、wrk
、JMeter
)模擬高并發場景,評估優化效果:
# 使用ab測試8080端口的并發性能
ab -n 10000 -c 100 http://localhost:8080/ # 發送10000個請求,并發100
根據測試結果(如QPS、響應時間、錯誤率)調整線程池、JVM或系統參數。
性能優化是持續過程,需根據應用負載變化(如用戶量增長、業務邏輯變更)定期復查配置,調整參數。例如:
maxThreads
和Xmx
;MaxMetaspaceSize
;