您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Tomcat性能調(diào)優(yōu)的方法是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Tomcat性能調(diào)優(yōu)的方法是什么”吧!
一切基于JVM(內(nèi)存)的優(yōu)化
2.1 32位操作系統(tǒng)與64位操作系統(tǒng)中JVM的對比
我們一般的開發(fā)人員,基本用的是都是32位的Windows系統(tǒng),這就導致了一個嚴重的問題即:32位windows系統(tǒng)對內(nèi)存限制,下面先來看一個比較的表格:
上述問題解決后,我們又碰到一個新的問題,32位系統(tǒng)下JVM對內(nèi)存的限制:不能突破2GB內(nèi)存,即使你在Win2003 Advanced Server下你的機器裝有8GB-16GB的內(nèi)存,而你的JAVA,只能用到2GB的內(nèi)存。
其實我一直很想推薦大家使用Linux或者是Mac操作系統(tǒng)的,而且要裝64位,因為必竟我們是開發(fā)用的不是打游戲用的,而Java源自Unix歸于Unix(Linux只是運行在PC上的Unix而己)。
所以很多開發(fā)人員運行在win32位系統(tǒng)上更有甚者在生產(chǎn)環(huán)境下都會布署win32位的系統(tǒng),那么這時你的Tomcat要優(yōu)化,就要講究點技巧了。而在64位操作系統(tǒng)上無論是系統(tǒng)內(nèi)存還是JVM都沒有受到2GB這樣的限制。
Tomcat的優(yōu)化分成兩塊:
Tomcat啟動命令行中的優(yōu)化參數(shù)即JVM優(yōu)化
Tomcat容器自身參數(shù)的優(yōu)化(這塊很像ApacheHttp Server)
這一節(jié)先要講的是Tomcat啟動命令行中的優(yōu)化參數(shù)。
Tomcat首先跑在JVM之上的,因為它的啟動其實也只是一個java命令行,首先我們需要對這個JAVA的啟動命令行進行調(diào)優(yōu)。
需要注意的是:
這邊討論的JVM優(yōu)化是基于Oracle Sun的jdk1.6版有以上,其它JDK或者低版本JDK不適用。
2.2 Tomcat啟動行參數(shù)的優(yōu)化
Tomcat 的啟動參數(shù)位于tomcat的安裝目錄in目錄下,如果你是Linux操作系統(tǒng)就是catalina.sh文件,如果你是Windows操作系統(tǒng)那么你需要改動的就是catalina.bat文件。打開該文件,一般該文件頭部是一堆的由##包裹著的注釋文字,找到注釋文字的最后一段如:
# $Id: catalina.sh 522797 2007-03-27 07:10:29Z fhanik $ # ----------------------------------------------------------------------------- # OS specific support. $var _must_ be set to either true or false.
敲入一個回車,加入如下的參數(shù)
Linux系統(tǒng)中tomcat的啟動參數(shù)
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系統(tǒng)中tomcat的啟動參數(shù)
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
上面參數(shù)好多啊,可能有人寫到現(xiàn)在都沒見一個tomcat的啟動命令里加了這么多參數(shù),當然,這些參數(shù)只是我機器上的,不一定適合你,尤其是參數(shù)后的value(值)是需要根據(jù)你自己的實際情況來設(shè)置的。
參數(shù)解釋:
-server
我不管你什么理由,只要你的tomcat是運行在生產(chǎn)環(huán)境中的,這個參數(shù)必須給我加上
因為tomcat默認是以一種叫java –client的模式來運行的,server即意味著你的tomcat是以真實的production的模式在運行的,這也就意味著你的tomcat以server模式運行時將擁有:更大、更高的并發(fā)處理能力,更快更強捷的JVM垃圾回收機制,可以獲得更多的負載與吞吐量。。。更。。。還有更。。。
Y給我記住啊,要不然這個-server都不加,那是要打屁股了。
-Xms–Xmx
即JVM內(nèi)存設(shè)置了,把Xms與Xmx兩個值設(shè)成一樣是最優(yōu)的做法,有人說Xms為最小值,Xmx為最大值不是挺好的,這樣設(shè)置還比較人性化,科學化。人性?科學?你個頭啊。
大家想一下這樣的場景:
一個系統(tǒng)隨著并發(fā)數(shù)越來越高,它的內(nèi)存使用情況逐步上升,上升到最高點不能上升了,開始回落,你們不要認為這個回落就是好事情,由其是大起大落,在內(nèi)存回落時它付出的代價是CPU高速開始運轉(zhuǎn)進行垃圾回收,此時嚴重的甚至會造成你的系統(tǒng)出現(xiàn)“卡殼”就是你在好好的操作,突然網(wǎng)頁像死在那邊一樣幾秒甚至十幾秒時間,因為JVM正在進行垃圾回收。
因此一開始我們就把這兩個設(shè)成一樣,使得Tomcat在啟動時就為最大化參數(shù)充分利用系統(tǒng)的效率,這個道理和jdbcconnection pool里的minpool size與maxpool size的需要設(shè)成一個數(shù)量是一樣的原理。
如何知道我的JVM能夠使用最大值啊?拍腦袋?不行!
在設(shè)這個最大內(nèi)存即Xmx值時請先打開一個命令行,鍵入如下的命令:
看,能夠正常顯示JDK的版本信息,說明,這個值你能夠用。不是說32位系統(tǒng)下最高能夠使用2GB內(nèi)存嗎?即:2048m,我們不防來試試
可以嗎?不可以!不要說2048m呢,我們小一點,試試1700m如何
嘿嘿,連1700m都不可以,更不要說2048m了呢,2048m只是一個理論數(shù)值,這樣說吧我這邊有幾臺機器,有的機器-Xmx1800都沒問題,有的機器最高只能到-Xmx1500m。
因此在設(shè)這個-Xms與-Xmx值時一定一定記得先這樣測試一下,要不然直接加在tomcat啟動命令行中你的tomcat就再也起不來了,要飛是飛不了,直接成了一只瘟貓了。
–Xmn
設(shè)置年輕代大小為512m。整個堆大小=年輕代大小 + 年老代大小 + 持久代大小。持久代一般固定大小為64m,所以增大年輕代后,將會減小年老代大小。此值對系統(tǒng)性能影響較大,Sun官方推薦配置為整個堆的3/8。
-Xss
是指設(shè)定每個線程的堆棧大小。這個就要依據(jù)你的程序,看一個線程 大約需要占用多少內(nèi)存,可能會有多少線程同時運行等。一般不易設(shè)置超過1M,要不然容易出現(xiàn)out ofmemory。
-XX:+AggressiveOpts
作用如其名(aggressive),啟用這個參數(shù),則每當JDK版本升級時,你的JVM都會使用最新加入的優(yōu)化技術(shù)(如果有的話)
-XX:+UseBiasedLocking
啟用一個優(yōu)化了的線程鎖,我們知道在我們的appserver,每個http請求就是一個線程,有的請求短有的請求長,就會有請求排隊的現(xiàn)象,甚至還會出現(xiàn)線程阻塞,這個優(yōu)化了的線程鎖使得你的appserver內(nèi)對線程處理自動進行最優(yōu)調(diào)配。
-XX:PermSize=128M-XX:MaxPermSize=256M
JVM使用-XX:PermSize設(shè)置非堆內(nèi)存初始值,默認是物理內(nèi)存的1/64;
在數(shù)據(jù)量的很大的文件導出時,一定要把這兩個值設(shè)置上,否則會出現(xiàn)內(nèi)存溢出的錯誤。
由XX:MaxPermSize設(shè)置最大非堆內(nèi)存的大小,默認是物理內(nèi)存的1/4。
那么,如果是物理內(nèi)存4GB,那么64分之一就是64MB,這就是PermSize默認值,也就是永生代內(nèi)存初始大小;
四分之一是1024MB,這就是MaxPermSize默認大小。
-XX:+DisableExplicitGC
在程序代碼中不允許有顯示的調(diào)用”System.gc()”??吹竭^有兩個極品工程中每次在DAO操作結(jié)束時手動調(diào)用System.gc()一下,覺得這樣做好像能夠解決它們的out ofmemory問題一樣,付出的代價就是系統(tǒng)響應(yīng)時間嚴重降低,就和我在關(guān)于Xms,Xmx里的解釋的原理一樣,這樣去調(diào)用GC導致系統(tǒng)的JVM大起大落,性能不到什么地方去喲!
-XX:+UseParNewGC
對年輕代采用多線程并行回收,這樣收得快。
-XX:+UseConcMarkSweepGC
即CMS gc,這一特性只有jdk1.5即后續(xù)版本才具有的功能,它使用的是gc估算觸發(fā)和heap占用觸發(fā)。
我們知道頻頻繁的GC會造面JVM的大起大落從而影響到系統(tǒng)的效率,因此使用了CMS GC后可以在GC次數(shù)增多的情況下,每次GC的響應(yīng)時間卻很短,比如說使用了CMS GC后經(jīng)過jprofiler的觀察,GC被觸發(fā)次數(shù)非常多,而每次GC耗時僅為幾毫秒。
-XX:MaxTenuringThreshold
設(shè)置垃圾最大年齡。如果設(shè)置為0的話,則年輕代對象不經(jīng)過Survivor區(qū),直接進入年老代。對于年老代比較多的應(yīng)用,可以提高效率。如果將此值設(shè)置為一個較大值,則年輕代對象會在Survivor區(qū)進行多次復制,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概率。
這個值的設(shè)置是根據(jù)本地的jprofiler監(jiān)控后得到的一個理想的值,不能一概而論原搬照抄。
-XX:+CMSParallelRemarkEnabled
在使用UseParNewGC 的情況下, 盡量減少 mark 的時間
-XX:+UseCMSCompactAtFullCollection
在使用concurrent gc 的情況下, 防止 memoryfragmention, 對live object 進行整理, 使 memory 碎片減少。
-XX:LargePageSizeInBytes
指定 Java heap的分頁頁面大小
-XX:+UseFastAccessorMethods
get,set 方法轉(zhuǎn)成本地代碼
-XX:+UseCMSInitiatingOccupancyOnly
指示只有在 oldgeneration 在使用了初始化的比例后concurrent collector 啟動收集
-XX:CMSInitiatingOccupancyFraction=70
CMSInitiatingOccupancyFraction,這個參數(shù)設(shè)置有很大技巧,基本上滿足(Xmx-Xmn)*(100- CMSInitiatingOccupancyFraction)/100>=Xmn就不會出現(xiàn)promotion failed。在我的應(yīng)用中Xmx是6000,Xmn是512,那么Xmx-Xmn是5488兆,也就是年老代有5488 兆,CMSInitiatingOccupancyFraction=90說明年老代到90%滿的時候開始執(zhí)行對年老代的并發(fā)垃圾回收(CMS),這時還 剩10%的空間是5488*10%=548兆,所以即使Xmn(也就是年輕代共512兆)里所有對象都搬到年老代里,548兆的空間也足夠了,所以只要滿 足上面的公式,就不會出現(xiàn)垃圾回收時的promotion failed;
因此這個參數(shù)的設(shè)置必須與Xmn關(guān)聯(lián)在一起。
-Djava.awt.headless=true
這個參數(shù)一般我們都是放在最后使用的,這全參數(shù)的作用是這樣的,有時我們會在我們的J2EE工程中使用一些圖表工具如:jfreechart,用于在web網(wǎng)頁輸出GIF/JPG等流,在winodws環(huán)境下,一般我們的app server在輸出圖形時不會碰到什么問題,但是在linux/unix環(huán)境下經(jīng)常會碰到一個exception導致你在winodws開發(fā)環(huán)境下圖片顯示的好好可是在linux/unix下卻顯示不出來,因此加上這個參數(shù)以免避這樣的情況出現(xiàn)。
上述這樣的配置,基本上可以達到:
系統(tǒng)響應(yīng)時間增快
JVM回收速度增快同時又不影響系統(tǒng)的響應(yīng)率
JVM內(nèi)存最大化利用
線程阻塞情況最小化
2.3 Tomcat容器內(nèi)的優(yōu)化
前面我們對Tomcat啟動時的命令進行了優(yōu)化,增加了系統(tǒng)的JVM可使用數(shù)、垃圾回收效率與線程阻塞情況、增加了系統(tǒng)響應(yīng)效率等還有一個很重要的指標,我們沒有去做優(yōu)化,就是吞吐量。
還記得我們在第三天的學習中說的,這個系統(tǒng)本身可以處理1000,你沒有優(yōu)化和配置導致它默認只能處理25。因此下面我們來看Tomcat容器內(nèi)的優(yōu)化。
打開tomcat安裝目錄confserver.xml文件,定位到這一行:
<Connector port=”8080″ protocol=”HTTP/1.1″
這一行就是我們的tomcat容器性能參數(shù)設(shè)置的地方,它一般都會有一個默認值,這些默認值是遠遠不夠我們的使用的,我們來看經(jīng)過更改后的這一段的配置:
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" />
好大一陀唉。
沒關(guān)系,一個個來解釋
URIEncoding=”UTF-8”
使得tomcat可以解析含有中文名的文件的url,真方便,不像apache里還有搞個mod_encoding,還要手工編譯
maxSpareThreads
maxSpareThreads 的意思就是如果空閑狀態(tài)的線程數(shù)多于設(shè)置的數(shù)目,則將這些線程中止,減少這個池中的線程總數(shù)。
minSpareThreads
最小備用線程數(shù),tomcat啟動時的初始化的線程數(shù)。
enableLookups
這個功效和Apache中的HostnameLookups一樣,設(shè)為關(guān)閉。
connectionTimeout
connectionTimeout為網(wǎng)絡(luò)連接超時時間毫秒數(shù)。
maxThreads
maxThreads Tomcat使用線程來處理接收的每個請求。這個值表示Tomcat可創(chuàng)建的最大的線程數(shù),即最大并發(fā)數(shù)。
acceptCount
acceptCount是當線程數(shù)達到maxThreads后,后續(xù)請求會被放入一個等待隊列,這個acceptCount是這個隊列的大小,如果這個隊列也滿了,就直接refuse connection
maxProcessors與minProcessors
在 Java中線程是程序運行時的路徑,是在一個程序中與其它控制線程無關(guān)的、能夠獨立運行的代碼段。它們共享相同的地址空間。多線程幫助程序員寫出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設(shè)成”false”,可以減少它對一些url的不必要的檢查從而減省開銷。
enableLookups=”false”
為了消除DNS查詢對性能的影響我們可以關(guān)閉DNS查詢,方式是修改server.xml文件中的enableLookups參數(shù)值。
disableUploadTimeout
類似于Apache中的keeyalive一樣
給Tomcat配置gzip壓縮(HTTP壓縮)功能
compression="on" compressionMinSize="2048" compressableMimeType="text/html,text/xml,text/javascript,text/css,text/plain"
HTTP 壓縮可以大大提高瀏覽網(wǎng)站的速度,它的原理是,在客戶端請求網(wǎng)頁后,從服務(wù)器端將網(wǎng)頁文件壓縮,再下載到客戶端,由客戶端的瀏覽器負責解壓縮并瀏覽。相對于普通的瀏覽過程HTML,CSS,Javascript , Text ,它可以節(jié)省40%左右的流量。更為重要的是,它可以對動態(tài)生成的,包括CGI、PHP , JSP , ASP , Servlet,SHTML等輸出的網(wǎng)頁也能進行壓縮,壓縮效率驚人。
1)compression=”on” 打開壓縮功能
2)compressionMinSize=”2048″ 啟用壓縮的輸出內(nèi)容大小,這里面默認為2KB
3)noCompressionUserAgents=”gozilla, traviata” 對于以下的瀏覽器,不啟用壓縮
4)compressableMimeType=”text/html,text/xml” 壓縮類型
最后不要忘了把8443端口的地方也加上同樣的配置,因為如果我們走https協(xié)議的話,我們將會用到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" />
舉個真實的例子:上一個項目,經(jīng)過4輪performance testing,第一輪進行了問題的定位,第二輪就是進行了apache+tomcat/weblogic的優(yōu)化,第三輪是做集群優(yōu)化,第四輪是sql與codes的優(yōu)化。好了,所有的Tomcat優(yōu)化的地方都加上了。結(jié)合第三天中的Apache的性能優(yōu)化,我們這個架構(gòu)可以“飛奔”起來了,當然這邊把有提及任何關(guān)于數(shù)據(jù)庫優(yōu)化的步驟,但僅憑這兩步,我們的系統(tǒng)已經(jīng)有了很大的提升。
在到達第二輪時,我們的性能已經(jīng)提升了多少倍呢?
左邊第一列是第一輪沒有經(jīng)過任何調(diào)優(yōu)的壓力測試報告。
右邊這一列是經(jīng)過了apache優(yōu)化,tomcat優(yōu)化后得到的壓力測試報告。
大家看看,這就提高了多少倍?這還只是在沒有改動代碼的情況下得到的改善,現(xiàn)在明白了好好的調(diào)優(yōu)一個apache和tomcat其實是多么的重要了?如果加上后面的代碼、SQL的調(diào)優(yōu)、數(shù)據(jù)庫的調(diào)優(yōu)。。。。。。所以我在上一個工程中有單筆交易性能(無論是吞吐量、響應(yīng)時間)提高了80倍這樣的極端例子的存在。
到此,相信大家對“Tomcat性能調(diào)優(yōu)的方法是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進入相關(guān)頻道進行查詢,關(guān)注我們,繼續(xù)學習!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。