Tomcat 生產環境配置優化
執行模式
Tomcat Connector三種執行模式(BIO, NIO, APR)的比較和優化。
org.apache.coyote.http11.Http11Protocol:BIO
org.apache.coyote.http11.Http11NioProtocol:NIO
org.apache.coyote.http11.Http11Nio2Protocol:NIO2
org.apache.coyote.http11.Http11AprProtocol:APR
BIO
一個執行緒處理一個請求。缺點:併發量高時,執行緒數較多,浪費資源。Tomcat7或以下,在Linux系統中預設使用這種方式。
NIO
利用Java的非同步IO處理,可以通過少量的執行緒處理大量的請求。Tomcat8在Linux系統中預設使用這種方式。Tomcat7必須修改Connector配置來啟動:
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443"/>
Tomcat8以後NIO2模式:
<Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" connectionTimeout="20000" redirectPort="8443"/>
APR
即Apache Portable Runtime,從作業系統層面解決io阻塞問題。Tomcat7或Tomcat8在Win7或以上的系統中啟動預設使用這種方式。Linux如果安裝了apr和native,Tomcat直接啟動就支援apr。
連線池
預設值:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
修改為:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="500" minSpareThreads="100" prestartminSpareThreads = "true" maxQueueSize = "100" />
引數解釋:
- maxThreads,最大併發數,預設設定 200,一般建議在 500 ~ 800,根據硬體設施和業務來判斷
- minSpareThreads,Tomcat 初始化時建立的執行緒數,預設設定 25
- prestartminSpareThreads,在 Tomcat 初始化的時候就初始化 minSpareThreads 的引數值,如果不等於 true,minSpareThreads 的值就沒啥效果了
- maxQueueSize,最大的等待佇列數,超過則拒絕請求
預設的連結引數配置:
<Connector
port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
/>
修改為:
<Connector executor="tomcatThreadPool"
port="8080"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
connectionTimeout="20000"
redirectPort="8443"/>
引數解釋:
- protocol,Tomcat 8 設定 nio2 更好:org.apache.coyote.http11.Http11Nio2Protocol
- protocol,Tomcat 6、7 設定 nio 更好:org.apache.coyote.http11.Http11NioProtocol
- enableLookups,禁用DNS查詢
- acceptCount,指定當所有可以使用的處理請求的執行緒數都被使用時,可以放到處理佇列中的請求數,超過這個數的請求將不予處理,預設設定 100
- maxPostSize,以 FORM URL 引數方式的 POST 提交方式,限制提交最大的大小,預設是 2097152(2兆),它使用的單位是位元組。10485760 為 10M。如果要禁用限制,則可以設定為 -1
- acceptorThreadCount,用於接收連線的執行緒的數量,預設值是1。一般這個指需要改動的時候是因為該伺服器是一個多核CPU,如果是多核 CPU 一般配置為 2
埠配置
Tomcat伺服器需配置三個端口才能啟動,安裝時預設啟用了這三個埠,當要執行多個tomcat服務時需要修改這三個埠。
<!-- 埠-1即可,標識隨機 -->
<Server port="-1" shutdown="SHUTDOWN">
<!-- 訪問埠,必須配置 -->
<Connector port="8080"
protocol="org.apache.coyote.http11.Http11Nio2Protocol"
connectionTimeout="20000"
redirectPort="8443"/>
<!-- 配置Apache使用,如果使用Nginx代理註釋掉即可 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
JVM 優化
Java 的記憶體模型分為:
-
Young,年輕代(易被 GC)。Young 區被劃分為三部分,Eden 區和兩個大小嚴格相同的 Survivor 區,其中 Survivor 區間中,某一時刻只有其中一個是被使用的,另外一個留做垃圾收集時複製物件用,在 Young 區間變滿的時候,minor GC 就會將存活的物件移到空閒的Survivor 區間中,根據 JVM 的策略,在經過幾次垃圾收集後,任然存活於 Survivor 的物件將被移動到 Tenured 區間。
-
Tenured,終身代。Tenured 區主要儲存生命週期長的物件,一般是一些老的物件,當一些物件在 Young 複製轉移一定的次數以後,物件就會被轉移到 Tenured 區,一般如果系統中用了 application 級別的快取,快取中的物件往往會被轉移到這一區間。
-
Perm,永久代。主要儲存 class,method,filed 物件,這部門的空間一般不會溢位,除非一次性載入了很多的類,不過在涉及到熱部署的應用伺服器的時候,有時候會遇到 java.lang.OutOfMemoryError : PermGen space 的錯誤,造成這個錯誤的很大原因就有可能是每次都重新部署,但是重新部署後,類的 class 沒有被解除安裝掉,這樣就造成了大量的 class 物件儲存在了 perm 中,這種情況下,一般重新啟動應用伺服器可以解決問題。
Linux 修改 /tomcat/bin/catalina.sh 檔案,把下面資訊新增到檔案第一行。
機子記憶體如果是 8G,一般 PermSize 配置是主要保證系統能穩定起來就行:
JAVA_OPTS="-Dfile.encoding=UTF-8 -server -Xms6144m -Xmx6144m -XX:NewSize=1024m -XX:MaxNewSize=2048m -XX:PermSize=512m -XX:MaxPermSize=512m -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:+DisableExplicitGC"
引數說明:
-Dfile.encoding:預設檔案編碼
-server:表示這是應用於伺服器的配置,JVM 內部會有特殊處理的
-Xmx1024m:設定JVM最大可用記憶體為1024MB
-Xms1024m:設定JVM最小記憶體為1024m。此值可以設定與-Xmx相同,以避免每次垃圾回收完成後JVM重新分配記憶體。
-XX:NewSize:設定年輕代大小
-XX:MaxNewSize:設定最大的年輕代大小
-XX:PermSize:設定永久代大小
-XX:MaxPermSize:設定最大永久代大小
-XX:NewRatio=4:設定年輕代(包括 Eden 和兩個 Survivor 區)與終身代的比值(除去永久代)。設定為 4,則年輕代與終身代所佔比值為 1:4,年輕代佔整個堆疊的 1/5
-XX:MaxTenuringThreshold=10:設定垃圾最大年齡,預設為:15。如果設定為 0 的話,則年輕代物件不經過 Survivor 區,直接進入年老代。對於年老代比較多的應用,可以提高效率。如果將此值設定為一個較大值,則年輕代物件會在 Survivor 區進行多次複製,這樣可以增加物件再年輕代的存活時間,增加在年輕代即被回收的概論。
-XX:+DisableExplicitGC:這個將會忽略手動呼叫 GC 的程式碼使得 System.gc() 的呼叫就會變成一個空呼叫,完全不會觸發任何 GC