本文檔主要介紹了Tomcat的性能調優的原理和方法。可做爲公司技術人員爲客戶Tomcat系統調優的技術指南,也能夠提供給客戶的技術人員做爲他們性能調優的指導手冊。html
因爲Tomcat的運行依賴於JVM,從虛擬機的角度咱們把Tomcat的調整分爲外部環境調優和自身調優兩類來描述。前端
調整Tomcat運行環境的操做系統參數和運行Tomcat的java虛擬機參數。java
Tomcat須要依賴Java虛擬機運行。根據客戶選用的主機的操做系統選擇對應的 JDK的版本。不管哪一個廠商的JDK,都建議使用最新的版本。linux
虛擬機可經過命令行的方式改變虛擬機使用內存的大小。以下表所示有兩個參數用來設置虛擬機使用內存的大小。程序員
參數web |
描述數據庫 |
-Xms<size>apache |
JVM初始化堆的大小編程 |
-Xmx<size>windows |
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設置爲應用所需的最小值,這樣會產生高效的垃圾回收。
以客戶系統爲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,那麼最好選擇服務器版本。由於在非服務器版本上,最終用戶受權數或者操做系統自己所能承受的用戶數、可用的網絡鏈接數或其它方面的一些方面都是有限制的。而且基於安全性的考慮,必須常常給操做系統打上最新的補丁。
雖然tomcat也能夠做web服務器,但其處理靜態html的速度比不上apache,且其做爲web服務器的功能遠不如apache,所以咱們想把 apache和tomcat集成起來,將html與jsp的功能部分進行明確分工,讓tomcat只處理jsp部分,其它的由apache,IIS等這些 web服務器處理,由此大大節省了tomcat有限的工做線程[LD3] 。
本節將說明Tomcat性能調優的技巧和方法,這些技巧和方法與操做系統或Java虛擬機的種類無關。如下方法都是針對Tomcat 性能自身調整的最佳方式。
當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查詢可能沒有大流量站點的效果明顯。
另一個可經過應用程序的鏈接器(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站點的流量都是同樣的,所以沒有一刀切的方案來肯定線程數的值。
當第一次訪問一個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而不是執行它。此舉唾手可得,不失爲一種檢驗頁面正確性的捷徑。
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已經啓動。其餘的配置請參考官方配置文檔。
前面咱們提到過操做系統經過一些限制手段來防止惡意的服務攻擊,一樣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>
若是沒有給出容許主機的指定,那麼與拒絕主機匹配的主機就會被拒絕,除此以外的都是容許的。與之相似,若是沒有給出拒絕主機的指定,那麼與容許主機匹配的主機就會被容許,除此以外的都是拒絕的。
在負載均衡的思路下,多臺服務器爲對等方式,每臺服務器都具備同等的地位,能夠單獨對外提供服務而無須其餘服務器的輔助。經過負載分擔技術,將外部發送來的請求按必定規則分配到對稱結構中的某一臺服務器上,而接收到請求的服務器都獨立迴應客戶機的請求。
提供服務的一組服務器組成了一個應用服務器集羣(cluster),集羣下的對等多機環境能夠增長系統的併發處理能力,和單臺機器出現故障系統的錯誤冗餘能力;同時實現了負載均衡和系統高可靠性。
四種實現負載均衡的方式:
第一是經過DNS,但只能實現簡單的輪流分配,不能處理故障;
第二若是是基於MS IIS,Windows 2003 server自己就帶了負載均衡服務;
第三是硬件方式,經過交換機的功能或專門的負載均衡設備能夠實現;
第四種是軟件方式,經過一臺負載均衡服務器進行,上面安裝軟件。使用Apache Httpd Server作負載平衡器。
客戶系統通常採用Apache httpd做爲web服務器,即做爲Tomcat的前端處理器,根據具體狀況而定,有些狀況下是不須要Apache httpd做爲 web 服務器的,如系統展示沒有靜態頁面那就不須要Apache httpd,那時能夠直接使用Tomcat做爲web 服務器來使用。使用Apache httpd主要是它在處理靜態頁面方面的能力比Tomcat強多了。以下圖:
在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 #++++++++++++++++++++++++++++++++++++++++++ |
同屬於一個集羣下的兩個服務實體,要求功能的同一性,因此咱們可先安裝和配置第一個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。
啓動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模塊起到了負載均衡的做用。
容量計劃是在生產環境中使用Tomcat不得不提的提升性能的另外一個重要的話題。若是你沒有對預期的網絡流量下的硬件和帶寬作考慮的話那麼不管你如何作配置修改和測試都無濟於事。
這裏先對說起的容量計劃做一個簡要的定義:容量計劃是指評估硬件、操做系統和網絡帶寬,肯定應用服務的服務範圍,尋求適合需求和軟件特性的軟硬件的一項活動。所以這裏所說的軟件不只包括Tomcat,也包括與Tomcat結合使用的任何第三方web服務器軟件。
如 果在購買軟硬件或部署系統前你對容量計劃一無所知,不知道現有的軟硬件環境可以支撐多少的訪問量,甚至更糟直到你已經交付而且在生產環境上部署產品後才意 識到配置有問題時再進行變動可能爲時已晚。此時只能增長硬件投入,增長硬盤容量甚至購買更好的服務器。若是事先作了容量計劃那麼就不會搞的如此焦頭爛額 了。
咱們這裏只介紹與Tomcat相關的內容。
首先爲了肯定Tomcat使用機器的容量計劃,你應該從一下列表項目種着手研究和計劃:
採用什麼樣的硬件體系?須要多少臺計算機?使用一個大型的,仍是使用多臺小型機?每一個計算機上使用幾個CPU?使用多少內存?使用什麼樣的存儲設備,I/O的處理速度有什麼要求?怎樣維護這些計算機?不一樣的JVM在這些硬件上運行的效果如何(好比IBM AIX系統只能在其設計的硬件系統上運行)?
帶寬的使用極限是多少?web應用程序如何處理過多的請求?
採用哪一種操做系統做爲站點服務器最好?在肯定的操做系統上使用哪一個JVM最好?例如,JVM在這種系統上是否支持本地多線程,對稱多處理?哪一種系統可以使web服務器更快、更穩定,而且更便宜。是否支持多CPU?
如下介紹針對Tomcat作容量計劃的步驟:
1) 量化負載。若是站點已經創建並運行,可使用工具模仿用戶訪問,肯定資源的需求量。
2) 針對測試結果或測試過程當中進行分析。須要知道那些請求形成了負載太重或者使用過多的資源,並與其它請求作比較,這樣就肯定了系統的瓶頸所在。例如:若是servlet在查詢數據庫的步驟上耗用較長的時間,那麼就須要考慮使用緩衝池來下降響應時間。
3)肯定性能最低標準。例如,你不想讓用戶花20秒來等待結果頁面的返回,也就是說甚至在達到訪問量的極限時,用戶等待的時間也不能超過20秒種(從點擊連接到看到返第一條返回數據)。這個時間中包含了數據庫查詢時間和文件訪問時間。同類產品性能在不一樣的公司可能有不一樣的標準,通常最好採起同行中的最低標準或對這個標準作出評估。
4)肯定如何合理使用底層資源,並逐一進行測試。底層資源包括CPU、內存、存儲器、帶寬、操做系統、JVM等等。在各類生產環境上都按順序進行部署和測試,觀察是否符合需求。在測試Tomcat時儘可能多采用幾種JVM,而且調整JVM使用內存和Tomcat線程池的大小進行測試。同時爲了達到資源充分合理穩定地使用的效果,還需針對測試過程當中出現的硬件系統瓶頸進行處理肯定合理的資源配置。這個過程最爲複雜,並且通常因爲沒有可參考的值因此只能靠理論推斷和經驗總結。
5) 若是經過第4步的反覆測試若是達到了最優的組合,就能夠在相同的生產環境上部署產品了。
此外應牢記必定要文檔化你的測試過程和結果,由於此後可能還會進行測試,這樣就能夠拿之前的測試結果做爲參考。另外測試過程要反覆屢次進行,每次的條件可能都不同,所以只有記錄下來才能進行結果比較和最佳條件的選擇。
這樣客戶系統經過測試找到了最好的組合方式,各類資源獲得了合理的配置,系統的性能獲得了極大的提高。