1. 程式人生 > >Tomcat 生產環境配置優化

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