1. 程式人生 > >tomcat優化實例

tomcat優化實例

定位 only 中文 RoCE compact 應用 urldecode ptc 就會

優化實例

啟動參數優化
JAVA_OPTS=‘-server -Xms512m -Xmx512m -XX:PermSize=64m -XX:MaxPermSize=512m -XX:+UseBiasedLocking -XX:+AggressiveOpts -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection‘

容器參數優化
<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
URIEncoding="UTF-8" minSpareThreads="20" maxSpareThreads="60" enableLookups="false" disableUploadTimeout="true"
connectionTimeout="20000"
acceptCount="800" maxThreads="800" maxProcessors="1000" minProcessors="5"
useURIValidationHack="false"
compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
redirectPort="8443" />

———————————————————————————————————————

一.運行模式優化

修改tomcat運行模式為nio
<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
... />

———————————————————————————————————————


二.啟動參數優化

export JAVA_OPTS="
-server
-Xms1024M //設置JVM的最小內存大小,此值推薦設置與-Xmx相同以此來避免每次垃圾回收完成後JVM重新分配內存。
-Xmx1024M //設置JVM的最大可用內存
-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是運行在生產環境中的,這個參數必須加上
因為tomcat默認是以一種叫java –client的模式來運行的,server即意味著你的tomcat是以真實的production的模式在運行的,這也就意味著你的tomcat以server模式運行時將擁有:更大、更高的並發處理能力,更快更強捷的JVM垃圾回收機制,可以獲得更多的負載與吞吐量。


# -Xms1024M -Xmx1024M

即JVM內存設置了,把Xms與Xmx兩個值設成一樣是最優的做法,有人說Xms為最小值,Xmx為最大值不是挺好的,這樣設置還比較人性化,科學化。
大家想一下這樣的場景:

一個系統隨著並發數越來越高,它的內存使用情況逐步上升,上升到最高點不能上升了,開始回落,你們不要認為這個回落就是好事情,由其是大起大落,在內存回落時它付出的代價是CPU高速開始運轉進行垃圾回收,此時嚴重的甚至會造成你的系統出現“卡殼”就是你在好好的操作,突然網頁像死在那邊一樣幾秒甚至十幾秒時間,因為JVM正在進行垃圾回收。

因此一開始我們就把這兩個設成一樣,使得Tomcat在啟動時就為最大化參數充分利用系統的效率,這個道理和jdbcconnection pool裏的minpool size與maxpool size的需要設成一個數量是一樣的原理。

# –Xmn

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

# -Xss512k

是指設定每個線程的堆棧大小。這個就要依據你的程序,看一個線程 大約需要占用多少內存,可能會有多少線程同時運行等。一般不易設置超過1M,要不然容易出現out ofmemory。

# -XX:+AggressiveOpts

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

# -XX:+UseBiasedLocking

啟用一個優化了的線程鎖,我們知道在我們的appserver,每個http請求就是一個線程,有的請求短有的請求長,就會有請求排隊的現象,甚至還會出現線程阻塞,這個優化了的線程鎖使得你的appserver內對線程處理自動進行最優調配。

# -XX:PermSize=128M -XX:MaxPermSize=256M

JVM使用-XX:PermSize設置非堆內存(持久代)初始值,默認是物理內存的1/64;

在數據量的很大的文件導出時,一定要把這兩個值設置上,否則會出現內存溢出的錯誤。

由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。

那麽,如果是物理內存4GB,那麽64分之一就是64MB,這就是PermSize默認值,也就是永生代內存初始大小;

四分之一是1024MB,這就是MaxPermSize默認大小。

# -XX:+DisableExplicitGC

在程序代碼中不允許有顯示的調用”System.gc()”。看到過有兩個極品工程中每次在DAO操作結束時手動調用System.gc()一下,覺得這樣做好像能夠解決它們的out ofmemory問題一樣,付出的代價就是系統響應時間嚴重降低,就和我在關於Xms,Xmx裏的解釋的原理一樣,這樣去調用GC導致系統的JVM大起大落,性能不到什麽地方去喲!

# -XX:+UseParNewGC

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

# -XX:+UseConcMarkSweepGC

即CMS gc,這一特性只有jdk1.5即後續版本才具有的功能,它使用的是gc估算觸發和heap占用觸發。

我們知道頻頻繁的GC會造面JVM的大起大落從而影響到系統的效率,因此使用了CMS GC後可以在GC次數增多的情況下,每次GC的響應時間卻很短,比如說使用了CMS GC後經過jprofiler的觀察,GC被觸發次數非常多,而每次GC耗時僅為幾毫秒。

# -XX:MaxTenuringThreshold=31

設置垃圾最大年齡。如果設置為0的話,則年輕代對象不經過Survivor區,直接進入年老代。對於年老代比較多的應用,可以提高效率。如果將此值設置為一個較大值,則年輕代對象會在Survivor區進行多次復制,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概率。

這個值的設置是根據本地的jprofiler監控後得到的一個理想的值,不能一概而論原搬照抄。

# -XX:+CMSParallelRemarkEnabled

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

# -XX:+UseCMSCompactAtFullCollection

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

# -XX:LargePageSizeInBytes=128m

指定 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下卻顯示不出來,因此加上這個參數以免避這樣的情況出現。

上述這樣的配置,基本上可以達到:

# 系統響應時間增快

# JVM回收速度增快同時又不影響系統的響應率

# JVM內存最大化利用

# 線程阻塞情況最小化

———————————————————————————————————————

三.Tomcat容器參數的優化

前面我們對Tomcat啟動時的命令進行了優化,增加了系統的JVM可使用數、垃圾回收效率與線程阻塞情況、增加了系統響應效率等還有一個很重要的指標,我們沒有去做優化,就是吞吐量。
下面我們來看Tomcat容器內的優化。

打開tomcat安裝目錄\conf\server.xml文件,定位到這一行:

<Connector port="8080" protocol="HTTP/1.1"
這一行就是我們的tomcat容器性能參數設置的地方,它一般都會有一個默認值,這些默認值是遠遠不夠我們的使用的,我們來看經過更改後的這一段的配置:

<Connector port="8080" protocol="HTTP/1.1"
URIEncoding="UTF-8" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000"
acceptCount="300" maxThreads="300" maxProcessors="1000" minProcessors="5"
useURIValidationHack="false"
compression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
redirectPort="8443"
/>

# URIEncoding=”UTF-8”

使得tomcat可以解析含有中文名的文件的url,真方便,不像apache裏還有搞個mod_encoding,還要手工編譯。


# maxSpareThreads

maxSpareThreads 的意思就是如果空閑狀態的線程數多於設置的數目,則將這些線程中止,減少這個池中的線程總數。


# minSpareThreads

最小備用線程數,tomcat啟動時的初始化的線程數。


# enableLookups

這個功效和Apache中的HostnameLookups一樣,設為關閉。


# connectionTimeout

connectionTimeout為網絡連接超時時間毫秒數。


# maxThreads

maxThreads Tomcat使用線程來處理接收的每個請求。這個值表示Tomcat可創建的最大的線程數,即最大並發數。


# acceptCount

acceptCount是當線程數達到maxThreads後,後續請求會被放入一個等待隊列,這個acceptCount是這個隊列的大小,如果這個隊列也滿了,就直接refuse connection


# maxProcessors與minProcessors

在 Java中線程是程序運行時的路徑,是在一個程序中與其它控制線程無關的、能夠獨立運行的代碼段。它們共享相同的地址空間。多線程幫助程序員寫出CPU最大利用率的高效程序,使空閑時間保持最低,從而接受更多的請求。
通常Windows是1000個左右,Linux是2000個左右。


# useURIValidationHack

我們來看一下tomcat中的一段源碼:

security
if (connector.getUseURIValidationHack()) {
String uri = validate(request.getRequestURI());
if (uri == null) {
res.setStatus(400);
res.setMessage("Invalid URI");
throw new IOException("Invalid URI");
} else {
req.requestURI().setString(uri);
// Redoing the URI decoding
req.decodedURI().duplicate(req.requestURI());
req.getURLDecoder().convert(req.decodedURI(), true);
}
}
可以看到如果把useURIValidationHack設成"false",可以減少它對一些url的不必要的檢查從而減省開銷。


# enableLookups="false"

為了消除DNS查詢對性能的影響我們可以關閉DNS查詢,方式是修改server.xml文件中的enableLookups參數值。


# disableUploadTimeout

類似於Apache中的keeyalive一樣


# 給Tomcat配置gzip壓縮(HTTP壓縮)功能

compression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
HTTP 壓縮可以大大提高瀏覽網站的速度,它的原理是,在客戶端請求網頁後,從服務器端將網頁文件壓縮,再下載到客戶端,由客戶端的瀏覽器負責解壓縮並瀏覽。相對於普通的瀏覽過程HTML,CSS,Javascript , Text ,它可以節省40%左右的流量。更為重要的是,它可以對動態生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等輸出的網頁也能進行壓縮,壓縮效率驚人。

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

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

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

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

最後不要忘了把8443端口的地方也加上同樣的配置,因為如果我們走https協議的話,我們將會用到8443端口這個段的配置,對吧?

<!--enable tomcat ssl-->
<Connector port="8443" protocol="HTTP/1.1"
URIEncoding="UTF-8" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true" connectionTimeout="20000"
acceptCount="300" maxThreads="300" maxProcessors="1000" minProcessors="5"
useURIValidationHack="false"
compression="on" compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
SSLEnabled="true"
scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="d:/tomcat2/conf/shnlap93.jks" keystorePass="aaaaaa"
/>
好了,所有的Tomcat優化的地方都加上了。結合Apache的性能優化,我們這個架構可以“飛奔”起來了,當然這邊把有提及任何關於數據庫優化的步驟,但僅憑這兩步,我們的系統已經有了很大的提升。


———————————————————————————————————————

生產應用配置

一.容器參數優化
<Connector port="80" protocol="org.apache.coyote.http11.Http11NioProtocol"
URIEncoding="UTF-8"
connectionTimeout="20000"
enableLookups="false"
disableUploadTimeout="true"
useURIValidationHack="false"
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
maxThreads="400"
minSpareThreads="20"
redirectPort="443"/>

二.啟動參數優化

export JAVA_OPTS=‘-server
-Xms1024m
-Xmx1024m
-Xss512k
-XX:PermSize=512m
-XX:MaxPermSize=512m
-XX:+UseParNewGC
-XX:+AggressiveOpts
-XX:+UseBiasedLocking
-XX:+DisableExplicitGC
-XX:+UseConcMarkSweepGC
-XX:+UseFastAccessorMethods
-XX:+CMSParallelRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:+UseCMSInitiatingOccupancyOnly‘

tomcat優化實例