Tomcat 調優總結


一. jvm參數調優

   常見的生產環境tomcat啟動腳本里常見如下的參數,我們依次來解釋各個參數意義.

   

export JAVA_OPTS="-server -Xms1400M -Xmx1400M -Xss512k -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:PermSize=128M -XX:MaxPermSize=256M -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=31 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -Djava.awt.headless=true "

 

 

  -server 

 如果tomcat是運行在生產環境中的,這個參數必須加上,-server參數可以使tomcat以server模式運行,這個模式下將擁有:更大、更高的並發處理能力,更快更強捷的JVM垃圾回收機 制,可以有更大的負載與吞吐量

-Xms<size>和-Xmx<size>  
      前者表示JVM初始化堆的大小,后者表示JVM堆的最大值。一般認為把Xms與Xmx兩個值設成一樣是最優的做法,否則會導致jvm有較為頻繁的GC,影響系統性能。因此一開始我們就把這兩個設成一樣,使得Tomcat在啟動時就為最大化參數充分利用系統的效率。 如何確定當前OS jvm最大可用內存呢?在命令行下執行    

java -Xmx2048 -version

 

   命令,如果提示下圖的信息,則證明當前內存數可以用

   

 

   如果提示下面的錯誤,則當前數值不可用.

    

 

 

-Xss

 

    設定每個線程的堆棧大小。依據具體應用,看一個線程大約占用多少內存、有多少線程同時運行等。一般不宜設置超過1M,要不然容易出現out ofmemory

–Xmn

    設置年輕代大小為512m。整個堆大小=年輕代大小 + 年老代大小 + 持久代大小。持久代一般固定大小為64m,所以增大年輕代后,將會減小年老代大小。此值對系統性能影響較大,Sun   官方推薦配置為整個堆的3/8。

 

 

-XX:+AggressiveOpts

 

  啟用這個參數,則每當JDK版本升級時,你的JVM都會使用最新加入的優化技術(如果有的話)

-XX:+UseBiasedLocking

  啟用一個優化了的線程鎖。對於應用服務器(ApplicationServer)來說每個http請求就是一個線程,由於請求需要的時長不一,在並發較大的時候會有請求排隊、甚至還會出現線程阻塞的現象,這個配置可以改善這個問題。

-XX:PermSize 和 -XX:MaxPermSize

  JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;使用XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。

  XX:MaxPermSize設置過小會導致java.lang.OutOfMemoryError,說說為什么會內存益出: 

(1)這一部分內存用於存放Class和Meta的信息,Class在被 Load的時候被放入PermGen space區域,它和存放Instance的Heap區域不同。 
(2)GC(Garbage Collection)不會在主程序運行期對PermGen space進行清理,所以如果你的APP會LOAD很多CLASS 的話,就很可能出現PermGen space錯誤。
  這種錯誤常見在web服務器對JSP進行pre compile的時候。  

XX:+DisableExplicitGC

在程序代碼中不允許有顯示的調用”System.gc()”。

-XX:+UseParNewGC

  對年輕代采用多線程並行回收,這樣收得快。

-XX:+UseConcMarkSweepGC

  即CMS gc,這一特性只有jdk1.5即后續版本才具有的功能,它使用的是gc估算觸發和heap占用觸發。
     我們知道頻頻繁的GC會造面JVM的大起大落從而影響到系統的效率,使用了CMS GC后可以在GC次數增多的情況下使每次GC的響應時間卻很短。

-XX:MaxTenuringThreshold

設置垃圾最大年齡。如果設置為0的話,則年輕代對象不經過Survivor區,直接進入年老代。對於年老代比較多的應用,可以提高效率。
如果將此值設置為一個較大值,則年輕代對象會在Survivor區進行多次復制,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概率。
這個值的設置是根據本地的jprofiler監控后得到的一個理想的值,不能一概而論原搬照抄。

 -XX:+CMSParallelRemarkEnabled

  在使用UseParNewGC 的情況下, 盡量減少 mark 的時間

-XX:+UseCMSCompactAtFullCollection

  在使用concurrent gc 的情況下, 防止 memoryfragmention, 對live object 進行整理, 使 memory 碎片減少。

-XX:LargePageSizeInBytes

  指定 Java heap的分頁頁面大小

-XX:+UseFastAccessorMethods

  get,set 方法轉成本地代碼

-XX:+UseCMSInitiatingOccupancyOnly

  指示只有在 oldgeneration 在使用了初始化的比例后concurrent collector 啟動收集

-XX:CMSInitiatingOccupancyFraction=70

CMSInitiatingOccupancyFraction,這個參數設置有很大技巧,基本上滿足
(Xmx-Xmn)*(100- CMSInitiatingOccupancyFraction)/100>=Xmn就不會出現promotion failed。
在我的應用中Xmx是6000,Xmn是512,那么Xmx-Xmn是5488兆,也就是年老代有5488 兆,CMSInitiatingOccupancyFraction=90
說明年老代到90%滿的時候開始執行對年老代的並發垃圾回收(CMS),這時還 剩10%的空間是5488*10%=548兆,
所以即使Xmn(也就是年輕代共512兆)里所有對象都搬到年老代里,548兆的空間也足夠了,所以只要滿足上面的公式
,就不會出現垃圾回收時的promotion failed;因此這個參數的設置必須與Xmn關聯在一起。

-Djava.awt.headless=true

這個參數一般我們都是放在最后使用的,這全參數的作用是這樣的,有時我們會在我們的J2EE工程中使用一些圖表工具如:jfreechart,用於在web網頁輸出GIF/JPG等流,在winodws環境下,一般我們的app server在輸出圖形時不會碰到什么問題,但是在linux/unix環境下經常會碰到一個exception導致你在winodws開發環境下圖片顯示的好好可是在linux/unix下卻顯示不出來,因此加上這個參數以免避這樣的情況出現。

-Dsun.net.client.defaultConnectTimeout=60000

      連接建立超時設置

-Dsun.net.client.defaultReadTimeout=60000

     內容獲取超時設置

-Djmagick.systemclassloader

    生成縮略圖的一個框架的配置=60000

-Dnetworkaddress.cache.ttl=300

    jvm dns緩存超時的設置

-Dsun.net.inetaddr.ttl=300

  jvm dns緩存超時的設置

 

 

 

二 .tomcat配置優化

 

 

在tomcat的server.xml中有類似:    

<Connector port="80" protocol="HTTP/1.1" 
    connectionTimeout="60000" 
    redirectPort="8443"
    maxThreads="5000" 
    acceptCount="500"
    minSpareThreads="100"
    maxSpareThreads="5000"
    enableLookups="false"
    compression="on"
    compressionMinSize="2048"
    compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
    disableUploadTimeout="true"
    URIEncoding="UTF-8"/>

的配置, 其中: 

 

port:   服務端口

protocol:  服務協議

connectionTimeout:  超時時間單位是ms,並發要求高的話,將此值減少!

redirectPort:   重定向端口 需要安全通信的場合,將把客戶請求轉發至SSL的redirectPort端口 

      acceptCount:  當指定的連接數被用盡時,可放到出列隊列中的數量,也即可接受的排隊數量.    

maxThreads:   Tomcat可創建的最大的線程數(每一個線程對應一個請求), maxThreads決定了tomcat的最大線程閥值,需要設置的大一些

minSpareThreads:   最小備用(空閑)線程數

maxSpareThreads:   最大備用(空閑)線程數,如果空閑線程超過這個值,Tomcat就會關閉不活動線程;

enableLookups:  關閉DNS查詢

URIEncoding:   設置tomcat默認的轉碼格式 查看$TOMCAT_HOME/webapps/tomcat-docs/config/http.html這個說明文檔,有如下說明: 

  URIEncoding:This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used. 

  也就是說,如果沒有設置URIEncoding, Tomcat默認是按ISO-8859-1進行URL解碼,ISO-8859-1並未包括中文字符,這樣的話中文字符肯定就不能被正確解析了。

 useURIValidationHack:  如果把useURIValidationHack設成"false",可以減少它對一些url的不必要的檢查從而減省開銷。

       disableUploadTimeout:       

       maxKeepAliveRequests: 
        表示該連接最大支持的請求次數。超過該請求數的連接也將被關閉(此時就會返回一個Connection: close頭給客戶端)
     keepAliveTimeout:
    表示在下次請求過來之前,tomcat保持該連接多久。這就是說假如客戶端不斷有請求過來,且每次連接間隔不超過這個值設置的時間,則該連接將一直保持。 

       compression、compressionMinSize、 compressableMimeType:omcat配置gzip壓縮(HTTP壓縮)功能   

1)compression="on" 打開壓縮功能

2)compressionMinSize="2048" 啟用壓縮的輸出內容大小,這里面默認為2KB

3)noCompressionUserAgents="gozilla, traviata" 對於以下的瀏覽器,不啟用壓縮

4)compressableMimeType="text/html,text/xml" 壓縮類型

 

在實現中,我們發現使用該配置,連接數上去之后很難下降,導致CPU一直維持在一個比較高的水平. 后來我們換了一種連接方式,采用線程池的方式,首先定義一個Executor: 

<Executor name="tomcatThreadPool" 
        namePrefix="tomcatThreadPool-" 
        maxThreads="1000" 
        maxIdleTime="300000"
        minSpareThreads="200"/>

參數的意義和上述相同 ,在Connector中使用定義的這個連接池:  

<Connector executor="tomcatThreadPool"
           port="20003" protocol="HTTP/1.1"
           acceptCount="800"
           minProcessors="300"
           maxProcessors = "1000"
           redirectPort="8443"/>

此處 minProcessors  參數對應前一種配置方式中的minSpareThreads, maxProcessors則與maxThreads意義差不多. 

使用連接池以后: 發現連接數上升之后如果一段時間內請求數下降了,連接數會很快下降,CPU的消耗也會隨之下降,處理能力得到了增強.

 

補充:

如何查看當前tomcat的連接數呢?

假設服務器上開啟了 2個tomcat實例,分別監聽8040和8050端口

netstat -na | grep ESTAB | grep 8040 | wc -l
netstat -na | grep ESTAB | grep 8050 | wc -l

二者之和,就是所有tomcat的連接數

 

 



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM