在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配置如下,增加并發性能
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以上版本);
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回收頻率 。
關于垃圾回收更詳細的文章請見:
下圖只是簡單的配置了:
JAVA_OPTS="-server -Xms1536m -Xmx1536m -Xss1024K -XX:PermSize=128m -XX:MaxPermSize=256m"
Tomcat堆內存的垃圾回收情況,可以看到默認是當系統使用到了閥值后進行GC回收
JVM 優化
模型資料來源:http://xmuzyq.iteye.com/blog/599750
配比資料:http://www.lxweimin.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 圖標,打開配置中有一個JavaTab 的進行編輯。
set JAVA_OPTS=%JAVA_OPTS% -Dfile.encoding="UTF-8" -Dsun.jnu.encoding="UTF8" -Ddefault.client.encoding="UTF-8" -Duser.language=Zhset 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可以使用同一個線程池來處理請求)
maxThreads="1000" minSpareThreads="50" maxIdleTime="600000"/>
executor="tomcatThreadPool" 指定使用的線程池
3.指定BlockingIO模式下的處理線程數目
maxThreads="150"http://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.配置示例
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">
...
管理AJP端口
AJP是為 Tomcat 與 HTTP 服務器之間通信而定制的協議,能提供較高的通信速度和效率。如果tomcat前端放的是apache的時候,會使用到AJP這個連接器。由于我們公司前端是由nginx做的反向代理,因此不使用此連接器,因此需要注銷掉該連接器。
默認 Tomcat 是開啟了對war包的熱部署的。為了防止被植入木馬等惡意程序,因此我們要關閉自動部署。
修改實例:
? ? ?