tomcat8性能優化


在tomcat/catalina.sh中加入下面的配置,內存要根據機器實際情況配置,如果配置內存太大了有可能機器很慢。

JAVA_OPTS="-server -Xms512m -Xmx512m -Xss1024K -XX:PermSize=64m -XX:MaxPermSize=128m"
JAVA_HOME=/root/jdk1.8.0_131
CATALINA_HOME=/root/apache-tomcat-8.5.13

 

JVM虛擬機的啟動配置 bin/catalina.sh

然后在tomat/conf/server.xml配置如下,增加並發性能

<Connector port="8080" protocol="HTTP/1.1"
maxThreads="500" minSpareThreads="100" enableLookups="false" URIEncoding="utf-8"
acceptCount="500" connectionTimeout="20000" disableUploadTimeout="ture" redirectPort="8443"/>

 

設定虛擬機的server啟動方式,以及堆內存的初始分配大小,垃圾收集機制,線程最大堆棧配置數,新生代內存大小等等

 

a 、JVM Server模式與client模式啟動,最主要的差別在於:-Server模式啟動時,速度較慢,但是一旦運行起來后,性能將會有很大的提升。JVM如果不顯式指定是-Server模式還是-client模式,JVM能夠根據下列原則進行自動判斷(適用於Java5版本或者Java以上版本);

JVM client模式和Server模式的區別

 

b、線程堆棧 -Xss 1024K 可以根據業務服務器的每次請求的大小來進行分配;

 

c、-xms -xmx  是 jvm占用最小和最大物理內存配置參數,一般講兩者配置一樣大,這樣就免去了內存不夠用時申請內存的耗時;

 

d、-XX:PermSize=128M -XX:MaxPermSize=128m

從前人的各類文章上了解到jvm的垃圾回收機制,這里只是簡單提一下, jvm的內存分為2大類型,一個是perm型,另一個是generation型。perm區域存放的是class這些靜態信息,一般默認64m,如果你的項目很大,有可能一啟動就報錯,out of memory permsize什么的,另外如果用spring框架的話很多類是動態反射加載的,運行一段時間有可能出現此異常,這種情況,設置下permsize就可以了。

另外一個類型才是重點,應用的代碼基本上在這個區域活動,new的類都會在這個區域,而且jvm決大部分工作都在這里搞了,這個區詳細說很復雜,有空去看sun資料,這里也只大概提下:這個區包含新生代和老生代區域,所有new出來的會放置在新區域,而多次回收失敗的一些一直被使用的實例則被轉移到老生代區域,所以新生代區域活動是最頻繁的。新生代內存不足時會促發一次 這個區的gc ----然后再到老生代的gc---最后才輪到full gc。full gc代價很高,應該盡量避免,盡量在newsize參數的這個區gc,一般配置 newsize分配到總內存1/4左右,---最終,如果full gc 還是內存不足,那就會引發out of memory 常見的那種。

-----------摘自jvm 參數優化---筆記

 

e、-XX:+UseParallelGC -XX:ParallelGCThreads=2 -XX:+UseAdaptiveSizePolicy
這幾個參數,一般的應用沒什么必要,UseParallelGC 並行回收,XX:ParallelGCThreads 並行回收線程數,只有配置了UseParallelGC有效。UseAdaptiveSizePolicy,讓jvm根據情況動態適配參數,當然如果你指定了某些參數,jvm就不會對那些參數再去調整的,加這個參數只要是讓我們考慮不全的其它參數能讓jvm幫忙做微處理。 總之UseParallelGC目的是 加快jvm回收頻率 。

關於垃圾回收更詳細的文章請見:

tomcat查看GC信息

 

下圖只是簡單的配置了:

JAVA_OPTS="-server -Xms1536m -Xmx1536m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m"

 

Tomcat堆內存的垃圾回收情況,可以看到默認是當系統使用到了閥值后進行GC回收

 

 

JVM 優化

  • 模型資料來源:http://xmuzyq.iteye.com/blog/599750
  • 配比資料:http://www.jianshu.com/p/d45e12241af4
  • 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 修改 /usr/program/tomcat7/bin/catalina.sh 文件,把下面信息添加到文件第一行。
    • 如果服務器只運行一個 Tomcat
      • 機子內存如果是 4G:
        • CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms2048m -Xmx2048m -Xmn1024m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
      • 機子內存如果是 8G:
        • CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms4096m -Xmx4096m -Xmn2048m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
      • 機子內存如果是 16G:
        • CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms8192m -Xmx8192m -Xmn4096m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
      • 機子內存如果是 32G:
        • CATALINA_OPTS="-Dfile.encoding=UTF-8 -server -Xms16384m -Xmx16384m -Xmn8192m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC"
    • 如果是 8G 開發機
      • -Xms2048m -Xmx2048m -XX:NewSize=512m -XX:MaxNewSize=1024m -XX:PermSize=256m -XX:MaxPermSize=512m
    • 如果是 16G 開發機
      • -Xms4096m -Xmx4096m -XX:NewSize=1024m -XX:MaxNewSize=2048m -XX:PermSize=256m -XX:MaxPermSize=512m
    • 參數說明:
     -Dfile.encoding:默認文件編碼
     -server:表示這是應用於服務器的配置,JVM 內部會有特殊處理的
     -Xmx1024m:設置JVM最大可用內存為1024MB
     -Xms1024m:設置JVM最小內存為1024m。此值可以設置與-Xmx相同,以避免每次垃圾回收完成后JVM重新分配內存。
     -Xmn1024m:設置JVM新生代大小(JDK1.4之后版本)。一般-Xmn的大小是-Xms的1/2左右,不要設置的過大或過小,過大導致老年代變小,頻繁Full GC,過小導致minor GC頻繁。如果不設置-Xmn,可以采用-XX:NewRatio=2來設置,也是一樣的效果
     -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:MaxTenuringThreshold,並不代表着,對象一定在年輕代存活15次才被晉升進入老年代,它只是一個最大值,事實上,存在一個動態計算機制,計算每次晉入老年代的閾值,取閾值和MaxTenuringThreshold中較小的一個為准。 -XX:+DisableExplicitGC:這個將會忽略手動調用 GC 的代碼使得 System.gc() 的調用就會變成一個空調用,完全不會觸發任何 GC
  • Windows 修改 /tomcat7/bin/catalina.bat 文件,找到這一行:echo Using CATALINA_BASE: "%CATALINA_BASE%",然后在其上面添加如下內容,此方法只對解壓版的 Tomcat 有效果,對於安裝版本的需要點擊安裝后任務欄上的那個 Tomcat 圖標,打開配置中有一個 Java Tab 的進行編輯。
set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding="UTF-8" -Dsun.jnu.encoding="UTF8" -Ddefault.client.encoding="UTF-8" -Duser.language=Zh set JAVA_OPTS=%JAVA_OPTS% -server -Xms4096m -Xmx4096m -Xmn2048m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:SurvivorRatio=10 -XX:MaxTenuringThreshold=15 -XX:NewRatio=2 -XX:+DisableExplicitGC




Server.xml的Connection優化

Tomcat的Connector是Tomcat接收HTTP請求的關鍵模塊,我們可以配置它來指定IO模式,以及處理通過這個Connector接受到的請求的處理線程數以及其它一些常用的HTTP策略。其主要配置參數如下: 

1.指定使用NIO模型來接受HTTP請求 
protocol="org.apache.coyote.http11.Http11NioProtocol" 指定使用NIO模型來接受HTTP請求。默認是BlockingIO,配置為protocol="HTTP/1.1" 
acceptorThreadCount="2" 使用NIO模型時接收線程的數目 

2.指定使用線程池來處理HTTP請求 
首先要配置一個線程池來處理請求(與Connector是平級的,多個Connector可以使用同一個線程池來處理請求) 
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" 
maxThreads="1000" minSpareThreads="50" maxIdleTime="600000"/> 
<Connector port="8080" 
executor="tomcatThreadPool" 指定使用的線程池 

3.指定BlockingIO模式下的處理線程數目 
maxThreads="150"//Tomcat使用線程來處理接收的每個請求。這個值表示Tomcat可創建的最大的線程數。默認值200。可以根據機器的時期性能和內存大小調整,一般可以在400-500。最大可以在800左右。 
minSpareThreads="25"---Tomcat初始化時創建的線程數。默認值4。如果當前沒有空閑線程,且沒有超過maxThreads,一次性創建的空閑線程數量。Tomcat初始化時創建的線程數量也由此值設置。 
maxSpareThreads="75"--一旦創建的線程超過這個值,Tomcat就會關閉不再需要的socket線程。默認值50。一旦創建的線程 超過此數值,Tomcat會關閉不再需要的線程。線程數可以大致上用 “同時在線人數*每秒用戶操作次數*系統平均操作時間” 來計算。 
acceptCount="100"----指定當所有可以使用的處理請求的線程數都被使用時,可以放到處理隊列中的請求數,超過這個數的請求將不予處 理。默認值10。如果當前可用線程數為0,則將請求放入處理隊列中。這個值限定了請求隊列的大小,超過這個數值的請求將不予處理。 
connectionTimeout="20000" --網絡連接超時,默認值20000,單位:毫秒。設置為0表示永不超時,這樣設置有隱患的。通常可設置為30000毫秒。 

4.其它常用設置 
maxHttpHeaderSize="8192" http請求頭信息的最大程度,超過此長度的部分不予處理。一般8K。 
URIEncoding="UTF-8" 指定Tomcat容器的URL編碼格式。 
disableUploadTimeout="true" 上傳時是否使用超時機制 
enableLookups="false"--是否反查域名,默認值為true。為了提高處理能力,應設置為false 
compression="on"   打開壓縮功能 
compressionMinSize="10240" 啟用壓縮的輸出內容大小,默認為2KB 
noCompressionUserAgents="gozilla, traviata"   對於以下的瀏覽器,不啟用壓縮 
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain" 哪些資源類型需要壓縮 

5.小結 
關於Tomcat的Nio和ThreadPool,本身的引入就提高了處理的復雜性,所以對於效率的提高有多少,需要實際驗證一下。 

6.配置示例 
<Connector port="8080" 
redirectPort="8443" 
maxThreads="150" 
minSpareThreads="25" 
maxSpareThreads="75" 
acceptCount="100" 
connectionTimeout="20000" 
protocol="HTTP/1.1" 

maxHttpHeaderSize="8192" 
URIEncoding="UTF-8" 
disableUploadTimeout="true" 
enableLookups="false" 
compression="on" 
compressionMinSize="10240" 
noCompressionUserAgents="gozilla, traviata" 
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"> 
... 
</Connector>

 

 

管理AJP端口

AJP是為 Tomcat 與 HTTP 服務器之間通信而定制的協議,能提供較高的通信速度和效率。如果tomcat前端放的是apache的時候,會使用到AJP這個連接器。由於我們公司前端是由nginx做的反向代理,因此不使用此連接器,因此需要注銷掉該連接器。

<!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->



默認 Tomcat 是開啟了對war包的熱部署的。為了防止被植入木馬等惡意程序,因此我們要關閉自動部署。

修改實例:

      <Host name="localhost"  appBase=""             unpackWARs="false" autoDeploy="false">
 


免責聲明!

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



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