tomcat是咱們經常使用的web容器,它的性能高低直接影響到應用對外提供服務的能力和用戶的體驗,因此tomcat的優化相當重要。對於單臺tomcat服務器而言,優化主要是兩方面:內存優化和配置優化(例如,鏈接數,線程池,iO等),固然還有使用tomcat原生庫。除了這些tomcat自己固有配置優化,還有一些減小佔用tomcat鏈接時間的配置,好比數據壓縮。若是單個服務器通過優化後依然沒法知足,性能要求,這時服務器集羣就是必須的手段了,下面針對這些方面的優化詳細介紹。javascript
tomcat用戶配置css
優化配置以前,咱們須要配置一個tomcat管理員帳戶,來登陸查看Tomcat控制檯提升的各類參數。在conf/ tomcat-users.xml下添加用戶:html
<role rolename="manager"/> <role rolename="manager-gui"/> <role rolename="admin"/> <role rolename="admin-gui"/> <user username="tomcat" password="tomcat" roles="admin-gui,admin,manager-gui,manager"/>
啓動tomcat,登陸查看信息:http://127.0.0.1:8080/:java
內存優化linux
主要是針對jvm各個內存大小的分配進行優化,以提升內存的使用率和減小資源變化帶來的時間消耗。有關文件:catalina.sh(linux下)或者catalina.bat(window下)。程序員
注意:對於32位操做系統上對jvm的內存有不能超過2G的限制,可是64位系統上沒有這個限制。但不少狀況下32操做系統上jvm的最大使用內存是不到2G的,2G只是個理想值,根據服務器的配置不一樣,可能有些只能用1500M或者1700M。具體支持多少,能夠在控制檯輸入:java -Xmx2089M -version,若是出現Java版本,說明你的jvm內存能夠設置到2089M。web
Linux系統中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 "
Windows系統中tomcat的啓動參數:數據庫
set 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
這個參數必須加上,由於tomcat默認是以一種叫java –client的模式來運行的,server即意味着你的tomcat是以真實的production的模式在運行的,這也就意味着你的tomcat以server模式運行時將擁有:更大、更高的併發處理能力,更快更強捷的JVM垃圾回收機制等。apache
Xms是JVM初始化時的內存大小;Xmx是jvm的最大內存大小。Xms默認是物理內存的1/64,Xmx默認是物理內存的1/4,建議是物理內存的80%,可是通常咱們會把Xms和Xmx設置同樣大,這樣在服務器啓動時就是最大值能夠避免內存膨脹和回落時帶來的資源的消耗。特別是回落時會帶來cpu的高速運轉進行垃圾回收,系統可能會出現幾秒甚至幾十秒的卡頓現象。
Xmn是年輕代大小。整個堆大小=年輕代大小 + 年老代大小 + 持久代大小。持久代通常固定大小爲64m,因此增大年輕代後,將會減少年老代大小。此值對系統性能影響較大,Sun官方推薦配置爲整個堆的3/8。
是指設定每一個線程的堆棧大小。這個就要依據你的程序,看一個線程 大約須要佔用多少內存,可能會有多少線程同時運行等。通常不易設置超過1M,要否則容易出現out ofmemory。
做用如其名(aggressive),啓用這個參數,則每當JDK版本升級時,你的JVM都會使用最新加入的優化技術(若是有的話)
啓用一個優化了的線程鎖,咱們知道在咱們的appserver,每一個http請求就是一個線程,有的請求短有的請求長,就會有請求排隊的現象,甚至還會出現線程阻塞,這個優化了的線程鎖使得你的appserver內對線程處理自動進行最優調配。
JVM使用-XX:PermSize設置非堆內存初始值,默認是物理內存的1/64;在數據量的很大的文件導出時,必定要把這兩個值設置上,不然會出現內存溢出的錯誤。由XX:MaxPermSize設置最大非堆內存的大小,默認是物理內存的1/4。那麼,若是是物理內存4GB,那麼64分之一就是64MB,這就是PermSize默認值,也就是永生代內存初始大小;四分之一是1024MB,這就是MaxPermSize默認大小。
PermGen space的全稱是Permanent Generationspace,是指內存的永久保存區域,這塊內存主要是被JVM存放Class和Meta信息的,Class在被Loader時就會被放到
PermGenspace中,它和存放類實例(Instance)的Heap區域不一樣,GC(GarbageCollection)不會在主程序運行期對PermGenspace進行清理,因此若是你的應用中有很CLASS的話,就極可能出現「java.lang.OutOfMemoryError:PermGen space」錯誤。
對於WEB項目,jvm加載類時,永久域中的對象急劇增長,從而使jvm不斷調整永久域大小,爲了不調整),你可使用更多的參數配置。若是你的WEBAPP下都用了大量的第三方jar, 其大小超過了jvm默認的大小,那麼就會產生此錯誤信息了。
在程序代碼中不容許有顯示的調用」System.gc()」。看到過有兩個極品工程中每次在DAO操做結束時手動調用System.gc()一下,以爲這樣作好像可以解決它們的out ofmemory問題同樣,付出的代價就是系統響應時間嚴重下降,就和我在關於Xms,Xmx裏的解釋的原理同樣,這樣去調用GC致使系統的JVM大起大落,性能不到什麼地方去喲!
對年輕代採用多線程並行回收,這樣收得快。
即CMS gc,這一特性只有jdk1.5即後續版本才具備的功能,它使用的是gc估算觸發和heap佔用觸發。
咱們知道頻頻繁的GC會造面JVM的大起大落從而影響到系統的效率,所以使用了CMS GC後能夠在GC次數增多的狀況下,每次GC的響應時間卻很短,好比說使用了CMS GC後通過jprofiler的觀察,GC被觸發次數很是多,而每次GC耗時僅爲幾毫秒。
設置垃圾最大年齡。若是設置爲0的話,則年輕代對象不通過Survivor區,直接進入年老代。對於年老代比較多的應用,能夠提升效率。若是將此值設置爲一個較大值,則年輕代對象會在Survivor區進行屢次複製,這樣能夠增長對象再年輕代的存活時間,增長在年輕代即被回收的機率。
這個值的設置是根據本地的jprofiler監控後獲得的一個理想的值,不能一律而論原搬照抄。
在使用UseParNewGC 的狀況下, 儘可能減小 mark 的時間
在使用concurrent gc 的狀況下, 防止 memoryfragmention, 對live object 進行整理, 使 memory 碎片減小。
指定 Java heap的分頁頁面大小
get,set 方法轉成本地代碼
指示只有在 oldgeneration 在使用了初始化的比例後concurrent collector 啓動收集
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關聯在一塊兒。
這個參數通常咱們都是放在最後使用的,這全參數的做用是這樣的,有時咱們會在咱們的J2EE工程中使用一些圖表工具如:jfreechart,用於在web網頁輸出GIF/JPG等流,在winodws環境下,通常咱們的app server在輸出圖形時不會碰到什麼問題,可是在linux/unix環境下常常會碰到一個exception致使你在winodws開發環境下圖片顯示的好好但是在linux/unix下卻顯示不出來,所以加上這個參數以避免避這樣的狀況出現。
上述這樣的配置,基本上能夠達到:
配置優化
主要是優化conf/server.xml文件中相關配置參數。
鏈接器優化
這裏主要是優化connector標籤中的相關參數,用於處理訪問的請求;固然此標籤中也能夠設置線程的相關參數,可是爲了更好的性能通常咱們使用外部的線程池,這樣有利於線程的複用,以減小線程的建立和銷燬帶來的資源消耗;另外,咱們也能夠修改tomcat的運行模式:BIO,NIO,AIO(NIO2),APR.
AJP鏈接器:
用於將Apache與Tomcat集成在一塊兒,當Apache接收到動態內容請求時,經過在配置中指定的端口號將請求發送給在此端口號上監聽的AJP鏈接器組件。
屬性:
backlog:當全部可能的請求處理線程都在使用時,隊列中排隊的請求最大數目。默認爲10,當隊列已滿,任何請求都將被拒絕
maxSpareThread:容許存在空閒線程的最大數目,默認值爲50
maxThread:最大線程數,默認值爲200
minSpareThreads:設當鏈接器第一次啓動時建立線程的數目,確保至少有這麼多的空閒線程可用,默認值爲4
port:服務端套接字的TCP端口號,默認值爲8089(必須)
topNoDelay:爲true時,能夠提升性能,默認值爲true
soTimeout:超時值
例:
<!—Define an AJP1.3 Connector on port 8089-->
<Connector port=」8089」 enableLookups=」false」 redirectPort=」8443」 protocol=」AJP/1.3」 />
AJPv13協議是面向包的。WEB服務器和Servlet容器經過TCP鏈接來交互;爲了節省SOCKET建立的昂貴代價,WEB服務器會嘗試維護一個永久TCP鏈接到servlet容器,而且在多個請求和響應週期過程會重用鏈接。咱們通常是使用Nginx+tomcat的架構,因此用不着AJP協議,因此把AJP鏈接器禁用。
2.Connector標籤常見參數的配置:
<Connector port="8080" protocol="HTTP/1.1"
//編碼格式
URIEncoding="UTF-8"
//線程配置
maxThreads="1000" maxProcessors="1000" minProcessors="5" minSpareThreads="100" maxSpareThreads="1000
//鏈接數配置
maxConnections="1000"
connectionTimeout="20000" acceptCount="1000"
//是否關閉DNS的反響查詢 false:關閉,true:開啓
enableLookups="false"
//是否保持長時間鏈接,false:關閉,ture:開啓
disableUploadTimeout="true"
//是否開啓對url進行校驗的配置 ,false:關閉,true:開啓
useURIValidationHack="false"
//啓用壓縮的配置
compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
//post請求提交最大大小
maxPostSize="10485760"
maxHttpHeaderSize="8192"
tcpNoDelay="true"
acceptorThreadCount="8"
redirectPort="8443" />
固然Connector標籤中的參數還有不少,這是隻是常見的參數設置;而且這些中的參數也不必定都要設置,須要根據項目的具體狀況去設置。
最後不要忘了把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中每個用戶請求都是一個線程,因此可使用線程池提升性能.在介紹Connector標籤中咱們看到已經有線程的相關參數的設置,爲何還要有線程池?其實這個和Java中的線程池是一個道理,使用線程池可使多鏈接公用線程,避免線程的頻繁的建立和銷燬帶來的資源消耗。
引入線程池的方法,使用Connector標籤中的executor的屬性,將其值設置爲Executor標籤的name的值。例如:
<Connector port="8066" executor="tomcatThreadPool" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" enableLookups="false" maxPostSize="10485760" URIEncoding="UTF-8" useBodyEncodingForURI="true"
acceptCount="100" acceptorThreadCount="2" disableUploadTimeout="true" maxConnections="10000" SSLEnabled="false" />
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-" maxThreads="1000" minSpareThreads="100" maxIdleTime="60000" maxQueueSize="Integer.MAX_VALUE" prestartminSpareThreads="false" threadPriority="5" className="org.apache.catalina.core.StandardThreadExecutor"/>
Executor線程池的參數介紹:
優化IO模式
tomcat中io模式通常分爲分別爲BIO(阻塞型IO),NIO,NIO2和APR。區別:
其實從上面的分析咱們並不能簡單的認爲BIO的性能就必定不如 NIO,這幾種類型 Connector之間並無明顯的性能區別,但它們之間實現流程和原理不一樣,因此它們的選擇是須要根據應用的類型來決定的。
修改io模式:
<Connector connectionTimeout="20000" port="8066" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8448"/>
從上面代碼能夠看出修改io模式其實就是修改connector標籤中的protocol屬性的值,其餘幾種io模式對應的值以下:
//BIO protocol="HTTP/1.1" //NIO protocol="org.apache.coyote.http11.Http11NioProtocol" //NIO2 protocol="org.apache.coyote.http11.Http11Nio2Protocol" //APR protocol="org.apache.coyote.http11.Http11AprProtocol"
監聽器Listener配置
另外一個影響Tomcat 性能的因素是內存泄露。Server標籤中能夠配置多個Listener,其中 JreMemoryLeakPreventionListener是用來預防JRE內存泄漏。此Listener只需在Server標籤中配置便可,默認狀況下無需配置,已經添加在 Server中
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
壓縮
壓縮也是tomcat性能優化比較中要的一部分,主要是經過connector標籤中的下面幾個參數來實現的
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等輸出的網頁也能進行壓縮,壓縮效率驚人。
數據庫性能調優
Tomcat性能在等待數據庫查詢被執行期間會下降。現在大多數應用程序都是使用可能包含「命名查詢」的關係型數據庫。若是是那樣的話,Tomcat會在啓動時默認加載命名查詢,這個可能會提高性能。另外一件重要事是確保全部數據庫鏈接正確地關閉。給數據庫鏈接池設置正確值也是十分重要的。我所說的值是指Resource要素的最大空閒數(maxIdle),最大鏈接數(maxActive),最大創建鏈接等待時間(maxWait)屬性的值。由於配置依賴與應用要求,我也不能在本文指定正確的值。你能夠經過調用數據庫性能測試來找到正確的值。固然數據庫調優自己就是一個功能好大且至關複雜的工做,後面咱們會專門研究如何進行數據調優!
tomcat原生庫
Tomcat的原生庫基於Apache可移植運行時(Apache Portable Runtime簡稱APR),給程序員提供了超強的擴展性和性能,在產品運做中幫助融合原生的服務器技術以展示最佳的性能。想知道安裝說明的朋友請參考Tomcat Native Library – (APR) Installation。
其餘優化措施
學習連接