一. 引言
性能測(cè)試與分析是軟件開(kāi)發(fā)過(guò)程中介于架構(gòu)和調(diào)整的一個(gè)廣泛并比較不容易理解的領(lǐng)域,更是一項(xiàng)較為復(fù)雜的活動(dòng)。就像下棋游戲一樣,有效的性能測(cè)試和分析只能在一個(gè)良好的計(jì)劃策略和具備了對(duì)不可預(yù)料事件的處理能力的條件下順利地完成。一個(gè)下棋高手贏得比賽靠的不僅僅是對(duì)游戲規(guī)則的認(rèn)識(shí),更是靠他的自己的能力和不斷地專注于分析自己對(duì)手的實(shí)力來(lái)更加有效地利用和發(fā)揮規(guī)則的作用。同樣一個(gè)優(yōu)秀的性能測(cè)試和分析人員將要面對(duì)的是來(lái)自一個(gè)全新的應(yīng)用程序和環(huán)境下帶來(lái)的整個(gè)項(xiàng)目的挑戰(zhàn)。本文中作者結(jié)合自己的使用經(jīng)驗(yàn)和參考文檔,對(duì)Tomcat性能方面的調(diào)整做一簡(jiǎn)要的介紹,并給出Tomcat性能的測(cè)試、分析和調(diào)整優(yōu)化的一些方法。
二. 測(cè)量Web服務(wù)器的性能
測(cè)量web服務(wù)器的性能是一項(xiàng)讓人感到畏縮的任務(wù),但是我們?cè)谶@里將給出一些需要注意的地方并且指點(diǎn)你了解其中更多的細(xì)節(jié)性的內(nèi)容。它不像一些簡(jiǎn)單的任務(wù),如測(cè)量CPU的速率或者是測(cè)量程序占用CPU的比例,web服務(wù)器的性能優(yōu)化中包括許調(diào)整許多變量來(lái)達(dá)到目標(biāo)。許多的測(cè)量策略中都包含了一個(gè)看似簡(jiǎn)單的瀏覽實(shí)際上是在向服務(wù)器發(fā)送大量的請(qǐng)求,我們稱之為客戶端的程序,來(lái)測(cè)量響應(yīng)時(shí)間??蛻舳撕头?wù)器端是在同一臺(tái)機(jī)器上嗎?服務(wù)器在測(cè)試的時(shí)候還運(yùn)行著其它的什么程序嗎?客戶端和服務(wù)器端的通訊是通過(guò)局域網(wǎng),100baseT,10baseT還是使用調(diào)制解調(diào)器?客戶端是否一直重復(fù)請(qǐng)求相同的頁(yè)面,還是隨機(jī)地訪問(wèn)不同的頁(yè)面?(這些影響到了服務(wù)緩存的性能)客戶端發(fā)送請(qǐng)求的有規(guī)律的還是突發(fā)的?你是在最終的配置環(huán)境下運(yùn)行服務(wù)的還是在調(diào)試的配置環(huán)境下運(yùn)行服務(wù)的?客戶端請(qǐng)求中包含圖片還是只有HTML頁(yè)面?是否有請(qǐng)求是通過(guò)servlets和JSP的,CGI程序,服務(wù)端包含(Server-Side Includes ,SSI是一個(gè)可以讓你使用動(dòng)態(tài)HTML文件的技術(shù))?所有這些都將是我們要關(guān)心的,并且?guī)缀跷覀儾豢赡芫_地把所有的問(wèn)題都清楚地列出來(lái)。
1.壓力測(cè)試工具
“工欲善其事,必先利其器”,壓力測(cè)試只有借助于一些工具才可得以實(shí)施。
大多數(shù)web壓力測(cè)試工具的實(shí)現(xiàn)原理都是通過(guò)重復(fù)的大量的頁(yè)面請(qǐng)求來(lái)模擬多用戶對(duì)被測(cè)系統(tǒng)的并發(fā)訪問(wèn),以此達(dá)到產(chǎn)生壓力的目的。產(chǎn)生壓力的手段都是通過(guò)錄制或者是編寫壓力腳本,這些腳本以多個(gè)進(jìn)程或者線程的形式在客戶端運(yùn)行,這樣通過(guò)人為制造各種類型的壓力,我們可以觀察被測(cè)系統(tǒng)在各種壓力狀況下的表現(xiàn),從而定位系統(tǒng)瓶頸,作為系統(tǒng)調(diào)優(yōu)的基礎(chǔ)。目前已經(jīng)存在的性能測(cè)試工具林林總總,數(shù)量不下一百種,從單一的開(kāi)放源碼的免費(fèi)小工具如 Aapache 自帶的 web 性能測(cè)試工具 Apache Benchmark、開(kāi)源的Jmeter 到大而全的商業(yè)性能測(cè)試軟件如 Mercury 的 LoadRunner 等等。任何性能測(cè)試工具都有其優(yōu)缺點(diǎn),我們可以根據(jù)實(shí)際情況挑選用最合適的工具。您可以在這里找到一些web壓力測(cè)試工具h(yuǎn)ttp://www.softwareqatest.com/qatweb1.html#LOAD
這里我們所使用的工具要支持web應(yīng)用服務(wù)認(rèn)證才可以,要支持接收發(fā)送cookies,不僅如此Tomcat支持多種認(rèn)證方式,比如基本認(rèn)證、基于表單的認(rèn)證、相互認(rèn)證和客戶端認(rèn)證,而一些工具僅僅支持HTTP基本認(rèn)證。真實(shí)地模擬用戶認(rèn)證是性能測(cè)試工具的一個(gè)重要的部分,因?yàn)檎J(rèn)證機(jī)制將對(duì)一個(gè)web站點(diǎn)的性能特征產(chǎn)生重要的影響?;谀阍诋a(chǎn)品中使用的不同的認(rèn)證方式,你需要從上面的工具列表中選擇使用這種特性的測(cè)試工具。
Apache Benchmark和http_load是命令行形式的工具,非常易于使用。Apache Benchmark可以模仿單獨(dú)的URL請(qǐng)求并且重復(fù)地執(zhí)行,可以使用不同的命令行參數(shù)來(lái)控制執(zhí)行迭代的次數(shù),并發(fā)用戶數(shù)等等。它的一個(gè)特點(diǎn)是可以周期性地打印出處理過(guò)程的信息,而其它工具只能給出一個(gè)全局的報(bào)告。
2.壓力測(cè)試工具介紹
三. 外部環(huán)境的調(diào)整
在Tomcat和應(yīng)用程序進(jìn)行了壓力測(cè)試后,如果您對(duì)應(yīng)用程序的性能結(jié)果不太滿意,就可以采取一些性能調(diào)整措施了,當(dāng)然了前提是應(yīng)用程序沒(méi)有問(wèn)題,我們這里只講Tomcat的調(diào)整。由于Tomcat的運(yùn)行依賴于JVM,所以在這里我們把Tomcat的調(diào)整可以分為兩類來(lái)詳細(xì)描述:
外部環(huán)境調(diào)整
調(diào)整非Tomcat組件,例如Tomcat運(yùn)行的操作系統(tǒng)和運(yùn)行Tomcat的java虛擬機(jī)。
自身調(diào)整
修改Tomcat自身的參數(shù),調(diào)整Tomcat配置文件中的參數(shù)。
下面我們將詳細(xì)講解外部環(huán)境調(diào)整的有關(guān)內(nèi)容,Tomcat自身調(diào)整的內(nèi)容將在第2部分中闡述。
1.JAVA虛擬機(jī)性能優(yōu)化
Tomcat本身不能直接在計(jì)算機(jī)上運(yùn)行,需要依賴于硬件基礎(chǔ)之上的操作系統(tǒng)和一個(gè)java虛擬機(jī)。您可以選擇自己的需要選擇不同的操作系統(tǒng)和對(duì)應(yīng)的JDK的版本(只要是符合Sun發(fā)布的Java規(guī)范的),但我們推薦您使用Sun公司發(fā)布的JDK。確保您所使用的版本是最新的,因?yàn)镾un公司和其它一些公司一直在為提高性能而對(duì)java虛擬機(jī)做一些升級(jí)改進(jìn)。一些報(bào)告顯示JDK1.4在性能上比JDK1.3提高了將近10%到20%。
可以給Java虛擬機(jī)設(shè)置使用的內(nèi)存,但是如果你的選擇不對(duì)的話,虛擬機(jī)不會(huì)補(bǔ)償。可通過(guò)命令行的方式改變虛擬機(jī)使用內(nèi)存的大小。如下表所示有兩個(gè)參數(shù)用來(lái)設(shè)置虛擬機(jī)使用內(nèi)存的大小。
參數(shù) |
描述 |
-Xms<size> |
JVM初始化堆的大小 |
-Xmx<size> |
JVM堆的最大值 |
這兩個(gè)值的大小一般根據(jù)需要進(jìn)行設(shè)置。初始化堆的大小執(zhí)行了虛擬機(jī)在啟動(dòng)時(shí)向系統(tǒng)申請(qǐng)的內(nèi)存的大小。一般而言,這個(gè)參數(shù)不重要。但是有的應(yīng)用程序在大負(fù)載的情況下會(huì)急劇地占用更多的內(nèi)存,此時(shí)這個(gè)參數(shù)就是顯得非常重要,如果虛擬機(jī)啟動(dòng)時(shí)設(shè)置使用的內(nèi)存比較小而在這種情況下有許多對(duì)象進(jìn)行初始化,虛擬機(jī)就必須重復(fù)地增加內(nèi)存來(lái)滿足使用。由于這種原因,我們一般把-Xms和-Xmx設(shè)為一樣大,而堆的最大值受限于系統(tǒng)使用的物理內(nèi)存。一般使用數(shù)據(jù)量較大的應(yīng)用程序會(huì)使用持久對(duì)象,內(nèi)存使用有可能迅速地增長(zhǎng)。當(dāng)應(yīng)用程序需要的內(nèi)存超出堆的最大值時(shí)虛擬機(jī)就會(huì)提示內(nèi)存溢出,并且導(dǎo)致應(yīng)用服務(wù)崩潰。因此一般建議堆的最大值設(shè)置為可用內(nèi)存的最大值的80%。
Tomcat默認(rèn)可以使用的內(nèi)存為128MB,在較大型的應(yīng)用項(xiàng)目中,這點(diǎn)內(nèi)存是不夠的,需要調(diào)大。
Windows下,在文件{tomcat_home}/bin/catalina.bat,Unix下,在文件{tomcat_home}/bin/catalina.sh的前面,增加如下設(shè)置:
JAVA_OPTS='-Xms【初始化內(nèi)存大小】 -Xmx【可以使用的最大內(nèi)存】'
需要把這個(gè)兩個(gè)參數(shù)值調(diào)大。例如:
JAVA_OPTS='-Xms256m -Xmx512m'
表示初始化內(nèi)存為256MB,可以使用的最大內(nèi)存為512MB。
另外需要考慮的是Java提供的垃圾回收機(jī)制。虛擬機(jī)的堆大小決定了虛擬機(jī)花費(fèi)在收集垃圾上的時(shí)間和頻度。收集垃圾可以接受的速度與應(yīng)用有關(guān),應(yīng)該通過(guò)分析實(shí)際的垃圾收集的時(shí)間和頻率來(lái)調(diào)整。如果堆的大小很大,那么完全垃圾收集就會(huì)很慢,但是頻度會(huì)降低。如果你把堆的大小和內(nèi)存的需要一致,完全收集就很快,但是會(huì)更加頻繁。調(diào)整堆大小的的目的是最小化垃圾收集的時(shí)間,以在特定的時(shí)間內(nèi)最大化處理客戶的請(qǐng)求。在基準(zhǔn)測(cè)試的時(shí)候,為保證最好的性能,要把堆的大小設(shè)大,保證垃圾收集不在整個(gè)基準(zhǔn)測(cè)試的過(guò)程中出現(xiàn)。
如果系統(tǒng)花費(fèi)很多的時(shí)間收集垃圾,請(qǐng)減小堆大小。一次完全的垃圾收集應(yīng)該不超過(guò) 3-5 秒。如果垃圾收集成為瓶頸,那么需要指定代的大小,檢查垃圾收集的詳細(xì)輸出,研究 垃圾收集參數(shù)對(duì)性能的影響。一般說(shuō)來(lái),你應(yīng)該使用物理內(nèi)存的 80% 作為堆大小。當(dāng)增加處理器時(shí),記得增加內(nèi)存,因?yàn)榉峙淇梢圆⑿羞M(jìn)行,而垃圾收集不是并行的。
[NextPage]
2.操作系統(tǒng)性能優(yōu)化
這里說(shuō)的操作系統(tǒng)是指運(yùn)行web服務(wù)器的系統(tǒng)軟件,當(dāng)然,不同的操作系統(tǒng)是為不同的目的而設(shè)計(jì)的。比如OpenBSD是面向安全的,因此在它的內(nèi)核中有許多的限制來(lái)防止不同形式的服務(wù)攻擊(OpenBSD的一句座右銘是“默認(rèn)是最安全的”)。這些限制或許更多地用來(lái)運(yùn)行活躍的web服務(wù)器。
而我們常用的Linux操作系統(tǒng)的目標(biāo)是易用使用,因此它有著更高的限制。使用BSD內(nèi)核的系統(tǒng)都帶有一個(gè)名為“Generic”的內(nèi)核,表明所有的驅(qū)動(dòng)器都靜態(tài)地與之相連。這樣就使系統(tǒng)易于使用,但是如果你要?jiǎng)?chuàng)建一個(gè)自定義的內(nèi)核來(lái)加強(qiáng)其中某些限制,那就需要排除不需要的設(shè)備。Linux內(nèi)核中的許多驅(qū)動(dòng)都是動(dòng)態(tài)地加載的。但是換而言之,內(nèi)存現(xiàn)在變得越來(lái)越便宜,所以因?yàn)榧虞d額外的設(shè)備驅(qū)動(dòng)就顯得不是很重要的。重要的是要有更多的內(nèi)存,并且在服務(wù)器上騰出更多的可用內(nèi)存。
小提示:雖然現(xiàn)在內(nèi)存已經(jīng)相當(dāng)?shù)谋阋耍€是盡量不要購(gòu)買便宜的內(nèi)存。那些有牌子的內(nèi)存雖然是貴一點(diǎn),但是從可靠性上來(lái)說(shuō),性價(jià)比會(huì)更高一些。
如果是在Windows操作系統(tǒng)上使用Tomcat,那么最好選擇服務(wù)器版本。因?yàn)樵诜欠?wù)器版本上,最終用戶授權(quán)數(shù)或者操作系統(tǒng)本身所能承受的用戶數(shù)、可用的網(wǎng)絡(luò)連接數(shù)或其它方面的一些方面都是有限制的。并且基于安全性的考慮,必須經(jīng)常給操作系統(tǒng)打上最新的補(bǔ)丁。
3.Tomcat與其它web服務(wù)器整合使用
雖然tomcat也可以作web服務(wù)器,但其處理靜態(tài)html的速度比不上apache,且其作為web服務(wù)器的功能遠(yuǎn)不如apache,因此我們想把a(bǔ)pache和tomcat集成起來(lái),將html與jsp的功能部分進(jìn)行明確分工,讓tomcat只處理jsp部分,其它的由apache,IIS等這些web服務(wù)器處理,由此大大節(jié)省了tomcat有限的工作“線程”。
4.負(fù)載均衡
在負(fù)載均衡的思路下,多臺(tái)服務(wù)器為對(duì)稱方式,每臺(tái)服務(wù)器都具有同等的地位,可以單獨(dú)對(duì)外提供服務(wù)而無(wú)須其他服務(wù)器的輔助。通過(guò)負(fù)載分擔(dān)技術(shù),將外部發(fā)送來(lái)的請(qǐng)求按一定規(guī)則分配到對(duì)稱結(jié)構(gòu)中的某一臺(tái)服務(wù)器上,而接收到請(qǐng)求的服務(wù)器都獨(dú)立回應(yīng)客戶機(jī)的請(qǐng)求。
提供服務(wù)的一組服務(wù)器組成了一個(gè)應(yīng)用服務(wù)器集群(cluster),并對(duì)外提供一個(gè)統(tǒng)一的地址。當(dāng)一個(gè)服務(wù)請(qǐng)求被發(fā)至該集群時(shí),根據(jù)一定規(guī)則選擇一臺(tái)服務(wù)器,并將服務(wù)轉(zhuǎn)定向給該服務(wù)器承擔(dān),即將負(fù)載進(jìn)行均衡分?jǐn)偂?BR> 通過(guò)應(yīng)用負(fù)載均衡技術(shù),使應(yīng)用服務(wù)超過(guò)了一臺(tái)服務(wù)器只能為有限用戶提供服務(wù)的限制,可以利用多臺(tái)服務(wù)器同時(shí)為大量用戶提供服務(wù)。當(dāng)某臺(tái)服務(wù)器出現(xiàn)故障時(shí),負(fù)載均衡服務(wù)器會(huì)自動(dòng)進(jìn)行檢測(cè)并停止將服務(wù)請(qǐng)求分發(fā)至該服務(wù)器,而由其他工作正常的服務(wù)器繼續(xù)提供服務(wù),從而保證了服務(wù)的可靠性。
負(fù)載均衡實(shí)現(xiàn)的方式大概有四種:第一是通過(guò)DNS,但只能實(shí)現(xiàn)簡(jiǎn)單的輪流分配,不能處理故障,第二如果是基于MS IIS,Windows 2003 server本身就帶了負(fù)載均衡服務(wù),第三是硬件方式,通過(guò)交換機(jī)的功能或?qū)iT的負(fù)載均衡設(shè)備可以實(shí)現(xiàn),第四種是軟件方式,通過(guò)一臺(tái)負(fù)載均衡服務(wù)器進(jìn)行,上面安裝軟件。使用Apache Httpd Server做負(fù)載平衡器,Tomcat集群節(jié)點(diǎn)使用Tomcat就可以做到以上第四種方式。這種方式比較靈活,成本相對(duì)也較低。另外一個(gè)很大的優(yōu)點(diǎn)就是可以根據(jù)應(yīng)用的情況和服務(wù)器的情況采取一些策略。
[NextPage]
四. 自身調(diào)整
本節(jié)將向您詳細(xì)介紹一些加速可使Tomcat實(shí)例加速運(yùn)行的技巧和方法,無(wú)論是在什么操作系統(tǒng)或者何種Java虛擬機(jī)上。在有些情況下,您可能沒(méi)有控制部署環(huán)境上的操作系統(tǒng)或者Java虛擬機(jī)。在這種情況下,您就需要逐行了解以下的的一些建議,然而你應(yīng)該在修改后使之生效。我認(rèn)為以下方法是Tomcat性能自身調(diào)整的最佳方式。
1.禁用DNS查詢
當(dāng)web應(yīng)用程序向要記錄客戶端的信息時(shí),它也會(huì)記錄客戶端的IP地址或者通過(guò)域名服務(wù)器查找機(jī)器名轉(zhuǎn)換為IP地址。DNS查詢需要占用網(wǎng)絡(luò),并且包括可能從很多很遠(yuǎn)的服務(wù)器或者不起作用的服務(wù)器上去獲取對(duì)應(yīng)的IP的過(guò)程,這樣會(huì)消耗一定的時(shí)間。為了消除DNS查詢對(duì)性能的影響我們可以關(guān)閉DNS查詢,方式是修改server.xml文件中的enableLookups參數(shù)值:
Tomcat4
<Connector className=org.apache.coyote.tomcat4.CoyoteConnector port=80 minProcessors=5 maxProcessors=75 enableLookups=false redirectPort=8443 acceptCount=100 debug=0 connectionTimeout=20000 useURIValidationHack=false disableUploadTimeout=true />
Tomcat5
<Connector port=80 maxThreads=150 minSpareThreads=25 maxSpareThreads=75 enableLookups=false redirectPort=8443 acceptCount=100 debug=0 connectionTimeout=20000 disableUploadTimeout=true/>
除非你需要連接到站點(diǎn)的每個(gè)HTTP客戶端的機(jī)器名,否則我們建議在生產(chǎn)環(huán)境上關(guān)閉DNS查詢功能。可以通過(guò)Tomcat以外的方式來(lái)獲取機(jī)器名。這樣不僅節(jié)省了網(wǎng)絡(luò)帶寬、查詢時(shí)間和內(nèi)存,而且更小的流量會(huì)使日志數(shù)據(jù)也會(huì)變得更少,顯而易見(jiàn)也節(jié)省了硬盤空間。對(duì)流量較小的站點(diǎn)來(lái)說(shuō)禁用DNS查詢可能沒(méi)有大流量站點(diǎn)的效果明顯,但是此舉仍不失為一良策。誰(shuí)又見(jiàn)到一個(gè)低流量的網(wǎng)站一夜之間就流量大增呢?
2.調(diào)整線程數(shù)
另外一個(gè)可通過(guò)應(yīng)用程序的連接器(Connector)進(jìn)行性能控制的的參數(shù)是創(chuàng)建的處理請(qǐng)求的線程數(shù)。Tomcat使用線程池加速響應(yīng)速度來(lái)處理請(qǐng)求。在Java中線程是程序運(yùn)行時(shí)的路徑,是在一個(gè)程序中與其它控制線程無(wú)關(guān)的、能夠獨(dú)立運(yùn)行的代碼段。它們共享相同的地址空間。多線程幫助程序員寫出CPU最大利用率的高效程序,使空閑時(shí)間保持最低,從而接受更多的請(qǐng)求。
Tomcat4中可以通過(guò)修改minProcessors和maxProcessors的值來(lái)控制線程數(shù)。這些值在安裝后就已經(jīng)設(shè)定為默認(rèn)值并且是足夠使用的,但是隨著站點(diǎn)的擴(kuò)容而改大這些值。minProcessors服務(wù)器啟動(dòng)時(shí)創(chuàng)建的處理請(qǐng)求的線程數(shù)應(yīng)該足夠處理一個(gè)小量的負(fù)載。也就是說(shuō),如果一天內(nèi)每秒僅發(fā)生5次單擊事件,并且每個(gè)請(qǐng)求任務(wù)處理需要1秒鐘,那么預(yù)先設(shè)置線程數(shù)為5就足夠了。但在你的站點(diǎn)訪問(wèn)量較大時(shí)就需要設(shè)置更大的線程數(shù),指定為參數(shù)maxProcessors的值。maxProcessors的值也是有上限的,應(yīng)防止流量不可控制(或者惡意的服務(wù)攻擊),從而導(dǎo)致超出了虛擬機(jī)使用內(nèi)存的大小。如果要加大并發(fā)連接數(shù),應(yīng)同時(shí)加大這兩個(gè)參數(shù)。web server允許的最大連接數(shù)還受制于操作系統(tǒng)的內(nèi)核參數(shù)設(shè)置,通常Windows是2000個(gè)左右,Linux是1000個(gè)左右。
在Tomcat5對(duì)這些參數(shù)進(jìn)行了調(diào)整,請(qǐng)看下表:
屬性名 |
描述 |
maxThreads |
Tomcat使用線程來(lái)處理接收的每個(gè)請(qǐng)求。這個(gè)值表示Tomcat可創(chuàng)建的最大的線程數(shù)。 |
acceptCount |
指定當(dāng)所有可以使用的處理請(qǐng)求的線程數(shù)都被使用時(shí),可以放到處理隊(duì)列中的請(qǐng)求數(shù),超過(guò)這個(gè)數(shù)的請(qǐng)求將不予處理。 |
connnectionTimeout |
網(wǎng)絡(luò)連接超時(shí),單位:毫秒。設(shè)置為0表示永不超時(shí),這樣設(shè)置有隱患的。通??稍O(shè)置為30000毫秒。 |
minSpareThreads |
Tomcat初始化時(shí)創(chuàng)建的線程數(shù)。 |
maxSpareThreads |
一旦創(chuàng)建的線程超過(guò)這個(gè)值,Tomcat就會(huì)關(guān)閉不再需要的socket線程。 |
最好的方式是多設(shè)置幾次并且進(jìn)行測(cè)試,觀察響應(yīng)時(shí)間和內(nèi)存使用情況。在不同的機(jī)器、操作系統(tǒng)或虛擬機(jī)組合的情況下可能會(huì)不同,而且并不是所有人的web站點(diǎn)的流量都是一樣的,因此沒(méi)有一刀切的方案來(lái)確定線程數(shù)的值。
[NextPage]
3.加速JSP編譯速度
當(dāng)?shù)谝淮卧L問(wèn)一個(gè)JSP文件時(shí),它會(huì)被轉(zhuǎn)換為Java serverlet源碼,接著被編譯成Java字節(jié)碼。你可以控制使用哪個(gè)編譯器,默認(rèn)情況下,Tomcat使用使用命令行javac進(jìn)行使用的編譯器。也可以使用更快的編譯器,但是這里我們將介紹如何優(yōu)化它們。
另外一種方法是不要把所有的實(shí)現(xiàn)都使用JSP頁(yè)面,而是使用一些不同的java模板引擎變量。顯然這是一個(gè)跨越很大的決定,但是事實(shí)證明至少這種方法是只得研究的。如果你想了解更多有關(guān)在Tomcat可使用的模板語(yǔ)言,你可以參考Jason Hunter和William Crawford合著的《Java Servlet Programming 》一書(O'Reilly公司出版)。
在Tomcat 4.0中可以使用流行而且免費(fèi)的Jikes編譯器。Jikes編譯器的速度要由于Sun的Java編譯器。首先要安裝Jikes(可訪問(wèn)http://oss.software.ibm.com/pub/jikes 獲得更多的信息),接著需要在環(huán)境變量中設(shè)置JIKESPATH包含系統(tǒng)運(yùn)行時(shí)所需的JAR文件。裝好Jikes以后還需要設(shè)置讓JSP編譯servlet使用Jikes,需要修改web.xml文件中jspCompilerPlugin的值:
<servlet> <servlet-name>jsp</servlet-name> <servlet-class> org.apache.jasper.servlet.JspServlet </servlet-class> <init-param> <param-name>logVerbosityLevel</param-name> <param-value>WARNING</param-value> </init-param> <init-param> <param-name>jspCompilerPlugin</param-name> <param-value> org.apache.jasper.compiler.JikesJavaCompiler </param-value> </init-param> <init-param> <!-- <param-name> org.apache.catalina.jsp_classpath </param-name> --> <param-name>classpath</param-name> <param-value> /usr/local/jdk1.3.1-linux/jre/lib/rt.jar: /usr/local/lib/java/servletapi/servlet.ja r</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet>
在Tomcat 4.1(或更高版本),JSP的編譯由包含在Tomcat里面的Ant程序控制器直接執(zhí)行。這聽(tīng)起來(lái)有一點(diǎn)點(diǎn)奇怪,但這正是Ant有意為之的一部分,有一個(gè)API文檔指導(dǎo)開(kāi)發(fā)者在沒(méi)有啟動(dòng)一個(gè)新的JVM的情況下,使用Ant。這是使用Ant進(jìn)行Java開(kāi)發(fā)的一大優(yōu)勢(shì)。另外,這也意味著你現(xiàn)在能夠在Ant中使用任何javac支持的編譯方式,這里有一個(gè)關(guān)于Apache Ant使用手冊(cè)的javac page列表。使用起來(lái)是容易的,因?yàn)槟阒恍枰?元素中定義一個(gè)名字叫“compiler”,并且在value中有一個(gè)支持編譯的編譯器名字,示例如下:
<servlet> <servlet-name>jsp</servlet-name> <servlet-class> org.apache.jasper.servlet.JspServlet </servlet-class> <init-param> <param-name>logVerbosityLevel</param-name> <param-value>WARNING</param-value> </init-param> <init-param> <param-name>compiler</param-name> <param-value>jikes</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet>
Ant可用的編譯器
名稱 |
別名 |
調(diào)用的編譯器 |
classic |
javac1.1, javac1.2 |
Standard JDK 1.1/1.2 compiler |
modern |
javac1.3, javac1.4 |
Standard JDK 1.3/1.4 compiler |
jikes |
|
The Jikes compiler |
JVC |
Microsoft |
Microsoft command-line compiler from the Microsoft SDK for Java/Visual J++ |
KJC |
|
The kopi compiler |
GCJ |
|
The gcj compiler (included as part of gcc) |
SJ |
Symantec |
Symantec's Java compiler |
extJavac |
|
Runs either the modern or classic compiler in a JVM of its own |
由于JSP頁(yè)面在第一次使用時(shí)已經(jīng)被編譯,那么你可能希望在更新新的jsp頁(yè)面后馬上對(duì)它進(jìn)行編譯。實(shí)際上,這個(gè)過(guò)程完全可以自動(dòng)化,因?yàn)榭梢源_認(rèn)的是新的JSP頁(yè)面在生產(chǎn)服務(wù)器和在測(cè)試服務(wù)器上的運(yùn)行效果是一樣的。
[NextPage]
在Tomcat4的bin目錄下有一個(gè)名為jspc的腳本。它僅僅是運(yùn)行翻譯階段,而不是編譯階段,使用它可以在當(dāng)前目錄生成Java源文件。它是調(diào)試JSP頁(yè)面的一種有力的手段。
可以通過(guò)瀏覽器訪問(wèn)再確認(rèn)一下編譯的結(jié)果。這樣就確保了文件被轉(zhuǎn)換成serverlet,被編譯了可直接執(zhí)行。這樣也準(zhǔn)確地模仿了真實(shí)用戶訪問(wèn)JSP頁(yè)面,可以看到給用戶提供的功能。也抓緊這最后一刻修改出現(xiàn)的bug并且修改它J
Tomcat提供了一種通過(guò)請(qǐng)求來(lái)編譯JSP頁(yè)面的功能。例如,你可以在瀏覽器地址欄中輸入http://localhost:8080/examples/jsp/dates/date.jsp?jsp_precompile=true,這樣Tomcat就會(huì)編譯data.jsp而不是執(zhí)行它。此舉唾手可得,不失為一種檢驗(yàn)頁(yè)面正確性的捷徑。
4. 其它
前面我們提到過(guò)操作系統(tǒng)通過(guò)一些限制手段來(lái)防止惡意的服務(wù)攻擊,同樣Tomcat也提供了防止惡意攻擊或禁止某些機(jī)器訪問(wèn)的設(shè)置。
Tomcat提供了兩個(gè)參數(shù)供你配置:RemoteHostValve 和RemoteAddrValve。
通過(guò)配置這兩個(gè)參數(shù),可以讓你過(guò)濾來(lái)自請(qǐng)求的主機(jī)或IP地址,并允許或拒絕哪些主機(jī)/IP。與之類似的,在Apache的httpd文件里有對(duì)每個(gè)目錄的允許/拒絕指定。
例如你可以把Admin Web application設(shè)置成只允許本地訪問(wèn),設(shè)置如下:
<Context path=/path/to/secret_files ...> <Valve className=org.apache.catalina.valves.RemoteAddrValve
allow=127.0.0.1 deny=/> </Context>
如果沒(méi)有給出允許主機(jī)的指定,那么與拒絕主機(jī)匹配的主機(jī)就會(huì)被拒絕,除此之外的都是允許的。與之類似,如果沒(méi)有給出拒絕主機(jī)的指定,那么與允許主機(jī)匹配的主機(jī)就會(huì)被允許,除此之外的都是拒絕的。
五. 容量計(jì)劃
容量計(jì)劃是在生產(chǎn)環(huán)境中使用Tomcat不得不提的提高性能的另一個(gè)重要的話題。如果你沒(méi)有對(duì)預(yù)期的網(wǎng)絡(luò)流量下的硬件和帶寬做考慮的話那么無(wú)論你如何做配置修改和測(cè)試都無(wú)濟(jì)于事。
這里先對(duì)提及的容量計(jì)劃作一個(gè)簡(jiǎn)要的定義:容量計(jì)劃是指評(píng)估硬件、操作系統(tǒng)和網(wǎng)絡(luò)帶寬,確定應(yīng)用服務(wù)的服務(wù)范圍,尋求適合需求和軟件特性的軟硬件的一項(xiàng)活動(dòng)。因此這里所說(shuō)的軟件不僅包括Tomcat,也包括與Tomcat結(jié)合使用的任何第三方web服務(wù)器軟件。
如果在購(gòu)買軟硬件或部署系統(tǒng)前你對(duì)容量計(jì)劃一無(wú)所知,不知道現(xiàn)有的軟硬件環(huán)境能夠支撐多少的訪問(wèn)量,甚至更糟直到你已經(jīng)交付并且在生產(chǎn)環(huán)境上部署產(chǎn)品后才意識(shí)到配置有問(wèn)題時(shí)再進(jìn)行變更可能為時(shí)已晚。此時(shí)只能增加硬件投入,增加硬盤容量甚至購(gòu)買更好的服務(wù)器。如果事先做了容量計(jì)劃那么就不會(huì)搞的如此焦頭爛額了。
我們這里只介紹與Tomcat相關(guān)的內(nèi)容。
首先為了確定Tomcat使用機(jī)器的容量計(jì)劃,你應(yīng)該從一下列表項(xiàng)目種著手研究和計(jì)劃:
1. 硬件
采用什么樣的硬件體系?需要多少臺(tái)計(jì)算機(jī)?使用一個(gè)大型的,還是使用多臺(tái)小型機(jī)?每個(gè)計(jì)算機(jī)上使用幾個(gè)CPU?使用多少內(nèi)存?使用什么樣的存儲(chǔ)設(shè)備,I/O的處理速度有什么要求?怎樣維護(hù)這些計(jì)算機(jī)?不同的JVM在這些硬件上運(yùn)行的效果如何(比如IBM AIX系統(tǒng)只能在其設(shè)計(jì)的硬件系統(tǒng)上運(yùn)行)?
2. 網(wǎng)絡(luò)帶寬
帶寬的使用極限是多少?web應(yīng)用程序如何處理過(guò)多的請(qǐng)求?
3. 服務(wù)端操作系統(tǒng)
采用哪種操作系統(tǒng)作為站點(diǎn)服務(wù)器最好?在確定的操作系統(tǒng)上使用哪個(gè)JVM最好?例如,JVM在這種系統(tǒng)上是否支持本地多線程,對(duì)稱多處理?哪種系統(tǒng)可使web服務(wù)器更快、更穩(wěn)定,并且更便宜。是否支持多CPU?
[NextPage]
4. Tomcat容量計(jì)劃
以下介紹針對(duì)Tomcat做容量計(jì)劃的步驟:
1) 量化負(fù)載。如果站點(diǎn)已經(jīng)建立并運(yùn)行,可以使用前面介紹的工具模仿用戶訪問(wèn),確定資源的需求量。
2) 針對(duì)測(cè)試結(jié)果或測(cè)試過(guò)程中進(jìn)行分析。需要知道那些請(qǐng)求造成了負(fù)載過(guò)重或者使用過(guò)多的資源,并與其它請(qǐng)求做比較,這樣就確定了系統(tǒng)的瓶頸所在。例如:如果servlet在查詢數(shù)據(jù)庫(kù)的步驟上耗用較長(zhǎng)的時(shí)間,那么就需要考慮使用緩沖池來(lái)降低響應(yīng)時(shí)間。
3) 確定性能最低標(biāo)準(zhǔn)。例如,你不想讓用戶花20秒來(lái)等待結(jié)果頁(yè)面的返回,也就是說(shuō)甚至在達(dá)到訪問(wèn)量的極限時(shí),用戶等待的時(shí)間也不能超過(guò)20秒種(從點(diǎn)擊鏈接到看到返第一條返回?cái)?shù)據(jù))。這個(gè)時(shí)間中包含了數(shù)據(jù)庫(kù)查詢時(shí)間和文件訪問(wèn)時(shí)間。同類產(chǎn)品性能在不同的公司可能有不同的標(biāo)準(zhǔn),一般最好采取同行中的最低標(biāo)準(zhǔn)或?qū)@個(gè)標(biāo)準(zhǔn)做出評(píng)估。
4) 確定如何合理使用底層資源,并逐一進(jìn)行測(cè)試。底層資源包括CPU、內(nèi)存、存儲(chǔ)器、帶寬、操作系統(tǒng)、JVM等等。在各種生產(chǎn)環(huán)境上都按順序進(jìn)行部署和測(cè)試,觀察是否符合需求。在測(cè)試Tomcat時(shí)盡量多采用幾種JVM,并且調(diào)整JVM使用內(nèi)存和Tomcat線程池的大小進(jìn)行測(cè)試。同時(shí)為了達(dá)到資源充分合理穩(wěn)定地使用的效果,還需針對(duì)測(cè)試過(guò)程中出現(xiàn)的硬件系統(tǒng)瓶頸進(jìn)行處理確定合理的資源配置。這個(gè)過(guò)程最為復(fù)雜,而且一般由于沒(méi)有可參考的值所以只能靠理論推斷和經(jīng)驗(yàn)總結(jié)。
5) 如果通過(guò)第4步的反復(fù)測(cè)試如果達(dá)到了最優(yōu)的組合,就可以在相同的生產(chǎn)環(huán)境上部署產(chǎn)品了。
此外應(yīng)牢記一定要文檔化你的測(cè)試過(guò)程和結(jié)果,因?yàn)榇撕罂赡苓€會(huì)進(jìn)行測(cè)試,這樣就可以拿以前的測(cè)試結(jié)果做為參考。另外測(cè)試過(guò)程要反復(fù)多次進(jìn)行,每次的條件可能都不一樣,因此只有記錄下來(lái)才能進(jìn)行結(jié)果比較和最佳條件的選擇。
這樣我們通過(guò)測(cè)試找到了最好的組合方式,各種資源得到了合理的配置,系統(tǒng)的性能得到了極大的提升。
六. 附加資料
很顯然本文也很難全面而詳盡地闡述性能優(yōu)化過(guò)程。如果你進(jìn)行更多研究的話可能會(huì)把性能調(diào)優(yōu)做的更好,比如Java程序的性能調(diào)整、操作系統(tǒng)的調(diào)整、各種復(fù)雜環(huán)境與應(yīng)用系統(tǒng)和其它所有與應(yīng)用程序相關(guān)的東西。在這里提供一些文中提到的一些資源、文中提到的相關(guān)內(nèi)容的鏈接以及本文的一些參考資料。
1. Web性能測(cè)試資料及工具
1) Jmeter Wiki首頁(yè),Jmeter為一個(gè)開(kāi)源的100%Java開(kāi)發(fā)的性能測(cè)試工具 http://wiki.apache.org/jakarta-jmeter/
2) Apache Benchmark使用說(shuō)明 http://httpd.apache.org/docs-2.0/programs/ab.html
3) 一些Java相關(guān)測(cè)試工具的介紹,包含可以與Tomcat集成進(jìn)行測(cè)試的工具 http://blog.csdn.net/wyingquan/
4) LoadRunner? 是一種預(yù)測(cè)系統(tǒng)行為和性能的工業(yè)標(biāo)準(zhǔn)級(jí)負(fù)載測(cè)試工具。它通過(guò)模擬數(shù)據(jù)以千萬(wàn)計(jì)用戶來(lái)實(shí)施并發(fā)負(fù)載來(lái)對(duì)整個(gè)企業(yè)架構(gòu)進(jìn)行測(cè)試,來(lái)幫助您更快的查找和發(fā)現(xiàn)問(wèn)題。 http://www.mercury.com/us/products/performance-center/loadrunner/
2. 文中介紹的相關(guān)內(nèi)容的介紹
1) Apache 2.x + Tomcat 4.x做負(fù)載均衡,描述了如何利用jk配置集群的負(fù)載均衡。 http://raibledesigns.com/tomcat/index.html
2) 容量計(jì)劃的制定,收集了許多有關(guān)制定web站點(diǎn)容量計(jì)劃的例子: http://www.capacityplanning.com/
3) 評(píng)測(cè)Tomcat5負(fù)載平衡與集群, http://www.javaresearch.org/article/showarticle.jsp?column=556&thread=19777
4) Apache與Tomcat的安裝與整合之整合篇 http://www.javaresearch.org/article/showarticle.jsp?column=23&thread=18139
5) 性能測(cè)試工具之研究,介紹了性能測(cè)試工具的原理與思路 http://www.51testing.com/emagzine/No2_2.htm
6) Java的內(nèi)存泄漏 http://www.matrix.org.cn/resource/article/409.html
7) Web服務(wù)器和應(yīng)用程序服務(wù)器有什么區(qū)別? http://www.matrix.org.cn/resource/article/1429.html
8) 詳細(xì)講解性能中數(shù)據(jù)庫(kù)集群的問(wèn)題 http://www.theserverside.com/articles/article.tss?l=DB_Break
|