1 概述

 

本文檔主要介紹了Tomcat的性能調優的原理和方法。可作為公司技術人員為客戶Tomcat系統調優的技術指南,也可以提供給客戶的技術人員作為他們性能調優的指導手冊。




 

2 調優分類

 

由於Tomcat的運行依賴于JVM,從虛擬機器的角度我們把Tomcat的調整分為外部環境調優和自身調優兩類來描述。
2.1 外部環境調優

 

調整Tomcat運行環境的作業系統參數和運行Tomcat的java虛擬機器參數。
2.1.1 JAVA虛擬機器性能優化

 

Tomcat需要依賴JAVA虛擬機器運行。根據客戶選用的主機的作業系統選擇對應的 JDK的版本。無論哪個廠商的JDK,都建議使用最新的版本。

 

虛擬機器可通過命令列的方式改變虛擬機器使用記憶體的大小。如下表所示有兩個參數用來設置虛擬機器使用記憶體的大小。

 

參數


 

描述

 

-Xms<size>


 

JVM初始化堆的大小

 

-Xmx<size>


 

JVM堆的最大值





 

Tomcat預設可以使用的記憶體為128MB,在較大型的應用專案中,這點記憶體是不夠的,需要調大。



 

  [LD1] Windows下,在檔tomcat_home/bin/catalina.bat,Unix下,在檔tomcat_home/bin/catalina.sh的前面,增加如下設置:



 

  JAVA_OPTS=‘-Xms【初始化記憶體大小】 -Xmx【可以使用的最大記憶體】’'



 

  需要把這個兩個參數值調大。例如:



 

  JAVA_OPTS='-Xms256m -Xmx512m'



 

  表示初始化記憶體為256MB,可以使用的最大記憶體為512MB。



 

另外需要考慮的是JAVA提供的垃圾回收機制。虛擬機器的堆大小決定了虛擬機器花費在收集垃圾上的時間和頻度。收集垃圾可以接受的速度與應用有關,應該通過分析實際的垃圾收集的時間和頻率來調整。



 

如果堆的空間很大,那麼完全垃圾收集(FULL GC)就會很慢,但是頻度會降低。如果在客戶系統中把堆的大小和記憶體的需要一致,完全收集就很快,但是會更加頻繁。調整堆大小的的目的是最小化垃圾收集的時間,以在特定的時間內最大化處理客戶的請求。對於SUN和HP等虛擬機器,推薦將最小堆大小和最大堆大小設置為同一值,因為這樣可以避免浪費用於時常調整堆大小所需的 VM 資源。



 

當然,客戶系統如果用到IBM虛擬機器,要特別的注意設置-Xms和-Xmx一樣大小會耽誤垃圾回收的開始直到堆滿,這樣第一次垃圾回收就會變成非常昂貴的操作。推薦把-Xms設置為應用所需的最小值,這樣會產生高效的垃圾回收。




 

2.1.2 作業系統性能優化

 

以客戶系統為HP-UX為例。



 

HP系統中對Tomcat有影響的參數:



 

其中:

 

max_thread_proc: 一個進程所能創建的執行緒的最大數

 

nkthread: 在系統上同時允許的核心執行緒的最大數

 

maxfiles上表給的建議是不是不合適?

 

如果在輸出裡看到消息:java.lang.OutOfMemoryError: unable to create new native thread,則說明名為 max_thread_proc 的 Unix 內核設置過小。max_thread_proc 是單個進程中的最大執行緒數。 它必須大到能夠容納 JAVA 應用程式中的所有線程以及虛擬機器本身中的部分額外線程。



 

查看核心參數:$ulimit -a

 

顯示[LD2] 輸出中的 nofiles 是指使用者的進程能同時打開的最大檔案控制代碼數。如果日誌中出現」two many open files」的異常,需要重點檢查這個參數。coredump 參數是 core 檔最大值的,限制當進程 coredump 時將產生 core檔的大小不能超過這個最大值。如果在日誌檔檢查時,發現 core檔不完整,需要增大這個參數值。執行 ulimit -n 命令可以設置 nofiles 參數,執行ulimit -c命令設置 core 檔最大值。



 

如果是在Windows作業系統上使用Tomcat,那麼最好選擇伺服器版本。因為在非伺服器版本上,最終使用者授權數或者作業系統本身所能承受的使用者數、可用的網路連接數或其它方面的一些方面都是有限制的。並且基於安全性的考慮,必須經常給作業系統打上最新的補丁。
2.1.3 Tomcat與其它web伺服器整合使用

 

雖然tomcat也可以作web伺服器,但其處理靜態html的速度比不上apache,且其作為web伺服器的功能遠不如apache,因此我們想把 apache和tomcat集成起來,將html與jsp的功能部分進行明確分工,讓tomcat只處理jsp部分,其它的由apache,IIS等這些 web伺服器處理,由此大大節省了tomcat有限的工作執行緒[LD3] 。




 

2.2 自身調優

 

本節將說明Tomcat性能調優的技巧和方法,這些技巧和方法與作業系統或JAVA虛擬機器的種類無關。以下方法都是針對Tomcat 性能自身調整的最佳方式。
2.2.1 禁用DNS查詢

 

當web應用程式要記錄用戶端的資訊時,它也會記錄用戶端的IP位址或者通過功能變數名稱伺服器查找機器名轉換為IP位址。DNS查詢需要佔用網路,並且包括可能從很多很遠的伺服器或者不起作用的伺服器上去獲取對應的IP的過程,這樣會消耗一定的時間。為了消除DNS查詢對性能的影響我們可以關閉DNS查詢,方式是修改server.xml 檔中的enableLookups參數值:

 

不同的tomcat版本稍有不同。

 

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」/>



 

除非客戶需要連接到網站的每個HTTP用戶端的機器名,否則我們建議在生產環境上關閉DNS查詢功能。可以通過Tomcat以外的方式來獲取機器名。這樣不僅節省了網路頻寬、查詢時間和記憶體,而且更小的流量會使日誌資料也會變得更少,顯而易見也節省了硬碟空間。對流量較小的網站來說禁用DNS查詢可能沒有大流量網站的效果明顯。


 

2.2.2 調整執行緒數

 

另外一個可通過應用程式的連接器(Connector)進行性能控制的參數是創建的處理請求的執行緒數。Tomcat使用執行緒池加速回應速度來處理請求。在JAVA中線程是程式運行時的路徑,是在一個程式中與其它控制執行緒無關的、能夠獨立運行的程式碼片段。它們共用相同的位址空間。多執行緒協助程式員寫出CPU最大利用率的高效程式,使閒置時間保持最低,從而接受更多的請求。



 

Tomcat4中可以通過修改minProcessors和maxProcessors的值來控制執行緒數。這些值在安裝後就已經設定為預設值並且是足夠使用的,但是隨著網站的擴容而改大這些值。minProcessors伺服器啟動時創建的處理請求的執行緒數應該足夠處理一個小量的負載。也就是說,如果一天內每秒僅發生5次按一下事件,並且每個請求任務處理需要1秒鐘,那麼預先設置執行緒數為5就足夠了。但在你的網站訪問量較大時就需要設置更大的執行緒數,指定為參數maxProcessors的值。maxProcessors的值也是有上限的,應防止流量不可控制(或者惡意的服務攻擊),從而導致超出了虛擬機器使用記憶體的大小。如果要加大併發連接數,應同時加大這兩個參數。web server允許的最大連接數還受制于作業系統的內核參數設置,通常Windows是2000個左右,Linux是1000個左右。



 

在Tomcat5對這些參數進行了調整,請看下表:

 

屬性名


 

描述

 

maxThreads


 

Tomcat使用執行緒來處理接收的每個請求。這個值表示Tomcat可創建的最大的執行緒數。

 

acceptCount


 

指定當所有可以使用的處理請求的執行緒數都被使用時,可以放到處理佇列中的請求數,超過這個數的請求將不予處理。

 

connnectionTimeout


 

網路連接超時,單位:毫秒。設置為0表示永不超時,這樣設置有隱患的。通常可設置為30000毫秒。

 

minSpareThreads


 

Tomcat初始化時創建的執行緒數。

 

maxSpareThreads


 

一旦創建的執行緒超過這個值,Tomcat就會關閉不再需要的socket執行緒。





 

最好的方式是多設置幾次並且進行測試,觀察回應時間和記憶體使用方式。在不同的機器、作業系統或虛擬機器組合的情況下可能會不同,而且並不是所有的web網站的流量都是一樣的,因此沒有一刀切的方案來確定執行緒數的值。
2.2.3 加速JSP編譯速度

 

當第一次訪問一個JSP檔時,它會被轉換為JAVA servlet源碼,接著被編譯成JAVA位元組碼。客戶工程師可以控制使用哪個編譯器,預設情況下,Tomcat使用命令列javac進行使用的編譯器。也可以使用更快的編譯器,這裡將介紹如何優化它們。

 

[LD4] 另外一種方法是不要把所有的實現都使用JSP頁面,而是使用一些不同的java範本引擎變數。

 

在Tomcat 4.0中可以使用流行而且免費的Jikes編譯器。Jikes編譯器的速度要高於Sun的JAVA編譯器。首先要安裝Jikes(可訪問HTTP://oss.software.ibm.com/pub/jikes 獲得更多的資訊),接著需要在環境變數中設置JIKESPATH包含系統運行時所需的JAR檔。裝好Jikes以後還需要設置讓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.jar
 
</param-value>
 
</init-param>
 
<load-on-startup>3</load-on-startup>
 
</servlet>


 
在Tomcat 4.1(或更高版本),JSP的编译由包含在Tomcat里面的Ant程序控制器直接执行。客户开发人员需要在元素中定义一个名字叫”compiler”,并且在value中有一个支持编译的编译器名字,示例如下:
 
<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[LD5] >












 
Ant可用的编译器
 
名称
 
别名
 
调用的编译器
 
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頁面在第一次使用時已經被編譯,那麼你可能希望在更新新的jsp頁面後馬上對它進行編譯。實際上,這個過程完全可以自動化,因為可以確認的是新的JSP頁面在生產伺服器和在測試伺服器上的運行效果是一樣的。
 
在Tomcat4的bin目錄下有一個名為jspc的腳本。它僅僅是運行翻譯階段,而不是編譯階段,使用它可以在目前的目錄生成JAVA原始檔案。它是調試JSP頁面的一種有力的手段。


 
可以通過瀏覽器訪問再確認一下編譯的結果。這樣就確保了檔被轉換成servlet,被編譯了可直接執行。這樣也準確地模仿了真實使用者訪問JSP頁面,可以看到給使用者提供的功能。也抓緊這最後一刻修改出現的bug並且修改它。


 
Tomcat提供了一種通過請求來編譯JSP頁面的功能。客戶可以在瀏覽器網址列中輸入HTTP://localhost: 8080/examples/jsp/dates/date.jsp?jsp_precompile=true,這樣Tomcat就會編譯 data.jsp而不是執行它。此舉唾手可得,不失為一種檢驗頁面正確性的捷徑。
2.2.4 NIO 配置
 
NIO (No-blocking I/O)從JDK 1.4起,NIO API作為一個基於緩衝區,並能提供非阻塞I/O操作的API被引入[LD6] 。
 
TOMCAT可以支援高併發的企業級應用。其中有個很大的原因就是,配置良好的tomcat都會使用APR(Apache Portable Runtime),APR是Apache HTTP Server2.x的核心,它是高度可移植的本地庫,它使用高性能的UXIN I/O操作,低性能的java io操作,但是APR對客戶開發人員而言可能稍稍有點難度,在很多OS平臺上,可能需要重新編譯APR。但是從Tomcat6.0以後, 客戶開發人員很容易就可以用NIO的技術來提升tomcat的併發處理能力。但是為什麼NIO可以提升tomcat的併發處理能力呢,我們先來看一下java 傳統io與 java NIO的差別。
JAVA 傳統的IO操作都是阻塞式的(blocking I/O), 如果有socket的程式設計基礎,你會接觸過堵塞socket和非堵塞socket,堵塞socket就是在accept、read、write等IO操作的時候,如果沒有可用符合條件的資源,不馬上返回,一直等待直到有資源為止。而非堵塞socket則是在執行select的時候,當沒有資源的時候堵塞,當有符合資源的時候,返回一個信號,然後程式就可以執行accept、read、write等操作,一般來說,如果使用堵塞socket,通常我們通常開一個執行緒accept socket,當讀完這次socket請求的時候,開一個單獨的執行緒這個socket請求;如果使用非堵塞socket,通常是只有一個執行緒,一開始是select狀,當有信號的時候可以通過多工(Multiplexing)技術傳遞給一個指定的執行緒池來處理請求,然後原來的執行緒繼續select狀態。 最簡單的多工技術可以通過java管道(Pipe)來實現。換句話說,如果用戶端的併發請求很大的時候,客戶系統可以使用少於用戶端併發請求的執行緒數來處理這些請求,而這些來不及立即處理的請求會被阻塞在java管道或者佇列裡面,等待中的執行緒池的處理。
 
在web伺服器上阻塞IO(BIO)與NIO一個比較重要的不同是,客戶系統使用BIO的時候往往會為每一個web請求引入多執行緒,每個web請求一個單獨的執行緒,所以併發量一旦上去了,執行緒數就上去了,CPU就忙著執行緒切換,所以BIO不合適高輸送量、高可伸縮的web伺服器;而NIO則是使用單線程(單個CPU)或者只使用少量的多執行緒(多CPU)來接受Socket,而由執行緒池來處理堵塞在pipe或者佇列裡的請求.這樣的話,只要OS可以接受TCP的連接,web伺服器就可以處理該請求。大大提高了web伺服器的可伸縮性。
 
客戶只需要在server.xml裡把 HTTP Connector做如下更改,
 
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
改為
<Connector port="8080" protocol="org.apache.coyote.HTTP11.Http11NioProtocol"
connectionTimeout="20000"
redirectPort="8443" />
 
然後啟動伺服器,如果出現org.apache.coyote.HTTP11.Http11NioProtocol start的提示資訊,表示NIO已經啟動。其他的配置請參考官方配置文檔。



 
2.2.5 其它
 
前面我們提到過作業系統通過一些限制手段來防止惡意的服務攻擊,同樣Tomcat也提供了防止惡意攻擊或禁止某些機器訪問的設置。
 
Tomcat提供了兩個參數供你配置:RemoteHostValve 和RemoteAddrValve。
 
通過配置這兩個參數,可以讓你過濾來自請求的主機或IP位址,並允許或拒絕哪些主機/IP。與之類似的,在Apache的HTTPd檔裡有對每個目錄的允許/拒絕指定。


 
例如你可以把Admin Web application設置成隻允許本地訪問,設置如下:
 
<CoNtext path=「/path/to/secret_files」 >
 
<Valve className=「org.apache.catalina.valves.RemoteAddrValve」
 
allow=「127.0.0.1」deny=「「/>
 
</CoNtext>


 
如果沒有給出允許主機的指定,那麼與拒絕主機匹配的主機就會被拒絕,除此之外的都是允許的。與之類似,如果沒有給出拒絕主機的指定,那麼與允許主機匹配的主機就會被允許,除此之外的都是拒絕的。
3 負載均衡
 
在負載均衡的思路下,多台伺服器為對等方式,每台伺服器都具有同等的地位,可以單獨對外提供服務而無須其他伺服器的輔助。通過負載分擔技術,將外部發送來的請求按一定規則分配到對稱結構中的某一台伺服器上,而接收到請求的伺服器都獨立回應客戶機的請求。
 
提供服務的一組伺服器組成了一個應用伺服器集群(cluster),集群下的對等多機環境可以增加系統的併發處理能力,和單台機器出現故障系統的錯誤冗余能力;同時實現了負載均衡和系統高可靠性。
 
四種實現負載均衡的方式:
 
第一是通過DNS,但只能實現簡單的輪流分配,不能處理故障;
 
第二如果是基於MS IIS,Windows 2003 server本身就帶了負載均衡服務;
 
第三是硬體方式,通過交換器的功能或專門的負載均衡設備可以實現;
 
第四種是軟體方式,通過一台負載均衡伺服器進行,上面安裝軟體。使用Apache Httpd Server做負載平衡器。
 
 
客戶系統一般採用Apache HTTPd作為web伺服器,即作為Tomcat的前端處理器,根據具體情況而定,有些情況下是不需要Apache HTTPd作為 web 伺服器的,如系統展現沒有靜態頁面那就不需要Apache HTTPd,那時可以直接使用Tomcat作為web 伺服器來使用。使用Apache HTTPd主要是它在處理靜態頁面方面的能力比Tomcat強多了。如下圖:





 
3.1.1 配置負載等化器
 
在apache下配置負載等化器分為三步,注意每次修改HTTPd.conf和workers2.properties時不要忘了重新開機apache。
 
第一步,安裝和調試apache
 
負載等化器jk2模組是apache www 服務的外掛程式,所以配置負載等化器就得先安裝apache。假設客戶下載的是windows版本 2.0.43,執行setup.exe並回答一些簡單問題就可完成apache的任務。值得注意的是,安裝並啟動apache後如果apache對HTTP://localhost/ 位址沒反應,你得修改apache安裝路徑下htdocs目錄下的index.html.xx檔,比如把index.html.en改成index.html。
 
第二步,安裝jk2
 
把下載到的 mod_jk2-2.0.43.dll改成mod_jk2.dll 放到apache的modules目錄下,修改apache的HTTPd.conf,即在LoadModule foo_module modules/mod_foo.so 行下插入mod_jk2模組的裝載資訊[LD7] :


 
# Example:
 
# LoadModule foo_module modules/mod_foo.so
 
#
 
LoadModule jk2_module modules/mod_jk2.dll




 
第三步,配置jk2
 
jk2的配置全在一個設定檔中,檔案名為workers2.properties,和apache 的HTTPd.conf放在同一個目錄下。以下是這個檔的內容:


 
#++++++++++++++++++++++++++++++++++++
 
# only at beginnin. In production uncomment it out
 
[logger.apache2]
 
level=DEBUG
 
#shm必須配
 
[shm]
 
file=D:\Program Files\Apache Group\Apache2\logs\shm.file
 
size=1048576
 
# 第一個tomcat 的位址
 
# Example socket channel, override port and host.
 
[channel.socket:tomcat1]
 
port=11009
 
host=127.0.0.1
 
# 定義第一個工作者指向第一個tomcat
 
# define the worker
 
[ajp13:tomcat1]
 
channel=channel.socket:tomcat1
 
#第二個tomcat 得位址
 
# Example socket channel, override port and host.
 
[channel.socket:tomcat2]
 
port=12009
 
host=10.1.36.123
 
# 定義第二個工作者指向第二個tomcat
 
# define the worker
 
[ajp13:tomcat2]
 
channel=channel.socket:tomcat2
 
#定義負載等化器,使其包含兩個工作者
 
[lb:lb1]
 
worker=ajp13:tomcat2
 
worker=ajp13:tomcat1
 
#指定負載等化器完成單一位址映射,使得apache 服務所在的uri全部指向 兩個tomcat 上的 root
 
# Uri mapping
 
[uri:/*]
 
group=lb:lb1
 
#++++++++++++++++++++++++++++++++++++++++++





 
3.1.2 配置tomcat
 
同屬於一個集群下的兩個服務實體,要求功能的同一性,所以我們可先安裝和配置第一個tomcat,接著拷貝形成第二個tomcat,最後配置第二個tomcat。


 
安裝tomcat 非常簡單,本文就不再描述。我們假設第一個tomcat的安裝路徑為d:\tomcat1。


 
配置第一個tomcat:
 
tomcat 中的jk2 connector缺省埠為8009,為了在一台機器上運行兩個tomcat,修改D:\Tomcat1\conf\jk2.properties,設置jk2 connector的埠為11009,整個檔內容如下:


 
#++++++++++++++
 
channelSocket.port=11009
 
#++++++++++++++




 
為了讓一台機器上運行兩個tomcat,修改server.conf的tomcat 停止指令監聽埠:


 
<Server port="8005" shutdown="SHUTDOWN" debug="0"> 改為
 
<Server port="11005" shutdown="SHUTDOWN" debug="0">


 
然後打開JK2 AJP connector ,關閉其它connector,下面是JK2 AJP 1.3的樣子,這裡已把它的埠改為11009:


 
<!-- Define a Coyote/JK2 AJP 1.3 Connector on port 8009 -->
 
<Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
 
port="11009" minProcessors="5" maxProcessors="75"
 
enableLookups="true" redirectPort="8443"
 
acceptCount="10" debug="0" connectionTimeout="20000"
 
useURIValidationHack="false"
 
protocolHandlerClassName="org.apache.jk.server.JkCoyoteHandler"/>


 
接著配置需要集群支援的webapp(比如examples) 的coNtext,添加如下manager:


 
<Manager
 
className="org.apache.catalina.session.InMemoryReplicationManager"
 
protocolStack="UDP(mcast_addr=228.1.2.3;mcast_port=45566;ip_ttl=32)
 
:PING(timeout=3000;
 
num_initial_members=6):FD(timeout=5000):VERIFY_SUSPECT(timeout=1500):
 
pbcast.STABLE(desired_avg_gossip=10000):pbcast.NAKACK(gc_lag=10;
 
retransmit_timeout=3000):UNICAST(timeout=5000;min_wait_time=2000):
 
MERGE2:FRAG:pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;
 
shun=false;print_local_addr=false)">
 
</Manager>


 
注意protocolStack的值必須在一行內寫完。
 
配置第二個tomcat:
 
把已經配好的第一個tomcat複製一份,形成第二個tomcat,假設路徑為d:\tomcat2。
 
修改D:\Tomcat2\conf\jk2.properties,設置jk2 connector的埠12009,整個檔內容如下:
 
#++++++++++++++
 
channelSocket.port=12009
 
#++++++++++++++
 
修改server.conf
 
有了第一個tomcat的配置我們只需修改server.conf的tomcat 停止指令監聽埠:
 
<Server port="11005" shutdown="SHUTDOWN" debug="0"> 改為
 
<Server port="12005" shutdown="SHUTDOWN" debug="0">




 
然後設置JK2 AJP connector 埠為12009。
 
3.1.3 運行測試
 
啟動apache,tomcat1和tomcat2。
 
 
我們先準備兩個檔,第一個檔為test.jsp,拷貝到第一個tomcat 的根web應用的目錄即d:\tomcat1\webapps\ROOT 下:


 
<html>
 
<body bgcolor="red">
 
<center>
 
<%= request.getSession().getId() %>
 
<h1>Tomcat 1</h1>
 
</body>
 
</html>




 
第二個檔也為test.jsp,拷貝到第二個tomcat 的根web應用的目錄即d:\tomcat2\webapps\ROOT 下:








 
<html>
 
<body bgcolor="blue">
 
<center>
 
<%= request.getSession().getId() %>
 
<h1>Tomcat 2</h1>
 
</body>
 
</html>




 
從不同的瀏覽器中多次輸入位址HTTP://localhost/test.jsp 會看到不同的顏色,這表明apache中的jk2模組起到了負載均衡的作用。













 
4 容量計劃
 
容量計劃是在生產環境中使用Tomcat不得不提的提高性能的另一個重要的話題。如果你沒有對預期的網路流量下的硬體和頻寬做考慮的話那麼無論你如何做配置修改和測試都無濟於事。


 
這裡先對提及的容量計劃作一個簡要的定義:容量計劃是指評估硬體、作業系統和網路頻寬,確定應用服務的服務範圍,尋求適合需求和軟體特性的軟硬體的一項活動。因此這裡所說的軟體不僅包括Tomcat,也包括與Tomcat結合使用的任何協力廠商web伺服器軟體。


 
如果在購買軟硬體或部署系統前你對容量計劃一無所知,不知道現有的軟硬體環境能夠支撐多少的訪問量,甚至更糟直到你已經交付並且在生產環境上部署產品後才意識到配置有問題時再進行變更可能為時已晚。此時只能增加硬體投入,增加硬碟容量甚至購買更好的伺服器。如果事先做了容量計劃那麼就不會搞的如此焦頭爛額了。


 
我們這裡只介紹與Tomcat相關的內容。


 
首先為了確定Tomcat使用機器的容量計劃,你應該從一下清單專案種著手研究和計畫:
4.1.1 硬體
 
採用什麼樣的硬體體系?需要多少台電腦?使用一個大型的,還是使用多台小型機?每個電腦上使用幾個CPU?使用多少記憶體?使用什麼樣的存放裝置,I/O的處理速度有什麼要求?怎樣維護這些電腦?不同的JVM在這些硬體上運行的效果如何(比如IBM AIX系統只能在其設計的硬體系統上運行)?
4.1.2 網路頻寬
 
頻寬的使用極限是多少?web應用程式如何處理過多的請求?
4.1.3 服務端作業系統
 
採用哪種作業系統作為網站伺服器最好?在確定的作業系統上使用哪個JVM最好?例如,JVM在這種系統上是否支援本地多執行緒,對稱多處理?哪種系統可使web伺服器更快、更穩定,並且更便宜。是否支援多CPU?
4.1.4 Tomcat容量計劃
 
以下介紹針對Tomcat做容量計劃的步驟:


 
1) 量化負載。如果網站已經建立並運行,可以使用工具模仿使用者訪問,確定資源的需求量。


 
2) 針對測試結果或測試過程中進行分析。需要知道那些請求造成了負載過重或者使用過多的資源,並與其它請求做比較,這樣就確定了系統的瓶頸所在。例如:如果servlet在查詢資料庫的步驟上耗用較長的時間,那麼就需要考慮使用緩衝集區來降低回應時間。


 
3)確定性能最低標準。例如,你不想讓使用者花20秒來等待結果頁面的返回,也就是說甚至在達到訪問量的極限時,使用者等待的時間也不能超過20秒種(從點選連結到看到返第一條返回資料)。這個時間中包含了資料庫查詢時間和檔存取時間。同類產品性能在不同的公司可能有不同的標準,一般最好採取同行中的最低標準或對這個標準做出評估。


 
4)確定如何合理使用底層資源,並逐一進行測試。底層資源包括CPU、記憶體、儲存體、頻寬、作業系統、JVM等等。在各種生產環境上都按順序進行部署和測試,觀察是否符合需求。在測試Tomcat時儘量多採用幾種JVM,並且調整JVM使用記憶體和Tomcat執行緒池的大小進行測試。同時為了達到資源充分合理穩定地使用的效果,還需針對測試過程中出現的硬體系統瓶頸進行處理確定合理的資源配置。這個過程最為複雜,而且一般由於沒有可參考的值所以只能靠理論推斷和經驗總結。


 
5) 如果通過第4步的反復測試如果達到了最優的組合,就可以在相同的生產環境上部署產品了。


 
此外應牢記一定要文檔化你的測試過程和結果,因為此後可能還會進行測試,這樣就可以拿以前的測試結果作為參考。另外測試過程要反復多次進行,每次的條件可能都不一樣,因此只有記錄下來才能進行結果比較和最佳條件的選擇。


 
這樣客戶系統通過測試找到了最好的組合方式,各種資源得到了合理的配置,系統的性能得到了極大的提升。
 
文章出處:飛諾網(www.firnow.com):HTTP://dev.firnow.com/course/3_program/java/javajs/20100719/460930.html


 
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()