Tomcat性能調優指南

 

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>
 

 

 

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>
 
 
 
 
 
 
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步的反覆測試如果達到了最優的組合,就可以在相同的生產環境上部署產品了。
 
此外應牢記一定要文檔化你的測試過程和結果,因爲此後可能還會進行測試,這樣就可以拿以前的測試結果作爲參考。另外測試過程要反覆多次進行,每次的條件可能都不一樣,因此只有記錄下來才能進行結果比較和最佳條件的選擇。
 
這樣客戶系統通過測試找到了最好的組合方式,各種資源得到了合理的配置,系統的性能得到了極大的提升。
<servlet-class>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章