調(diào)整非Tomcat組件,例如Tomcat運行的操作系統(tǒng)和運行Tomcat的java虛擬機。
自身調(diào)整
修改Tomcat自身的參數(shù),調(diào)整Tomcat配置文件中的參數(shù)。
下面我們將詳細講解外部環(huán)境調(diào)整的有關(guān)內(nèi)容,Tomcat自身調(diào)整的內(nèi)容將在第2部分中闡述。
1.JAVA虛擬機性能優(yōu)化
Tomcat本身不能直接在計算機上運行,需要依賴于硬件基礎(chǔ)之上的操作系統(tǒng)和一個java虛擬機。您可以選擇自己的需要選擇不同的操作系統(tǒng)和對應(yīng)的JDK的版本(只要是符合Sun發(fā)布的Java規(guī)范的),但我們推薦您使用Sun公司發(fā)布的JDK。確保您所使用的版本是最新的,因為Sun公司和其它一些公司一直在為提高性能而對java虛擬機做一些升級改進。一些報告顯示JDK1.4在性能上比JDK1.3提高了將近10%到20%。
可以給Java虛擬機設(shè)置使用的內(nèi)存,但是如果你的選擇不對的話,虛擬機不會補償。可通過命令行的方式改變虛擬機使用內(nèi)存的大小。如下表所示有兩個參數(shù)用來設(shè)置虛擬機使用內(nèi)存的大小。
參數(shù) | 描述 |
-Xms<size> | JVM初始化堆的大小 |
-Xmx<size> | JVM堆的最大值 |
這兩個值的大小一般根據(jù)需要進行設(shè)置。初始化堆的大小執(zhí)行了虛擬機在啟動時向系統(tǒng)申請的內(nèi)存的大小。一般而言,這個參數(shù)不重要。但是有的應(yīng)用程序在大負載的情況下會急劇地占用更多的內(nèi)存,此時這個參數(shù)就是顯得非常重要,如果虛擬機啟動時設(shè)置使用的內(nèi)存比較小而在這種情況下有許多對象進行初始化,虛擬機就必須重復(fù)地增加內(nèi)存來滿足使用。由于這種原因,我們一般把-Xms和-Xmx設(shè)為一樣大,而堆的最大值受限于系統(tǒng)使用的物理內(nèi)存。一般使用數(shù)據(jù)量較大的應(yīng)用程序會使用持久對象,內(nèi)存使用有可能迅速地增長。當(dāng)應(yīng)用程序需要的內(nèi)存超出堆的最大值時虛擬機就會提示內(nèi)存溢出,并且導(dǎo)致應(yīng)用服務(wù)崩潰。因此一般建議堆的最大值設(shè)置為可用內(nèi)存的最大值的80%。
Tomcat默認可以使用的內(nèi)存為128MB,在較大型的應(yīng)用項目中,這點內(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)存】'
需要把這個兩個參數(shù)值調(diào)大。例如:
JAVA_OPTS='-Xms256m -Xmx512m'
表示初始化內(nèi)存為256MB,可以使用的最大內(nèi)存為512MB。
另外需要考慮的是Java提供的垃圾回收機制。虛擬機的堆大小決定了虛擬機花費在收集垃圾上的時間和頻度。收集垃圾可以接受的速度與應(yīng)用有關(guān),應(yīng)該通過分析實際的垃圾收集的時間和頻率來調(diào)整。如果堆的大小很大,那么完全垃圾收集就會很慢,但是頻度會降低。如果你把堆的大小和內(nèi)存的需要一致,完全收集就很快,但是會更加頻繁。調(diào)整堆大小的的目的是最小化垃圾收集的時間,以在特定的時間內(nèi)最大化處理客戶的請求。在基準測試的時候,為保證最好的性能,要把堆的大小設(shè)大,保證垃圾收集不在整個基準測試的過程中出現(xiàn)。
如果系統(tǒng)花費很多的時間收集垃圾,請減小堆大小。一次完全的垃圾收集應(yīng)該不超過 3-5 秒。如果垃圾收集成為瓶頸,那么需要指定代的大小,檢查垃圾收集的詳細輸出,研究 垃圾收集參數(shù)對性能的影響。一般說來,你應(yīng)該使用物理內(nèi)存的 80% 作為堆大小。當(dāng)增加處理器時,記得增加內(nèi)存,因為分配可以并行進行,而垃圾收集不是并行的。
2、操作系統(tǒng)性能優(yōu)化
這里說的操作系統(tǒng)是指運行web服務(wù)器的系統(tǒng)軟件,當(dāng)然,不同的操作系統(tǒng)是為不同的目的而設(shè)計的。比如OpenBSD是面向安全的,因此在它的內(nèi)核中有許多的限制來防止不同形式的服務(wù)攻擊(OpenBSD的一句座右銘是“默認是最安全的”)。這些限制或許更多地用來運行活躍的web服務(wù)器。
而我們常用的Linux操作系統(tǒng)的目標是易用使用,因此它有著更高的限制。使用BSD內(nèi)核的系統(tǒng)都帶有一個名為“Generic”的內(nèi)核,表明所有的驅(qū)動器都靜態(tài)地與之相連。這樣就使系統(tǒng)易于使用,但是如果你要創(chuàng)建一個自定義的內(nèi)核來加強其中某些限制,那就需要排除不需要的設(shè)備。Linux內(nèi)核中的許多驅(qū)動都是動態(tài)地加載的。但是換而言之,內(nèi)存現(xiàn)在變得越來越便宜,所以因為加載額外的設(shè)備驅(qū)動就顯得不是很重要的。重要的是要有更多的內(nèi)存,并且在服務(wù)器上騰出更多的可用內(nèi)存。
小提示:雖然現(xiàn)在內(nèi)存已經(jīng)相當(dāng)?shù)谋阋耍€是盡量不要購買便宜的內(nèi)存。那些有牌子的內(nèi)存雖然是貴一點,但是從可靠性上來說,性價比會更高一些。
如果是在Windows操作系統(tǒng)上使用Tomcat,那么最好選擇服務(wù)器版本。因為在非服務(wù)器版本上,最終用戶授權(quán)數(shù)或者操作系統(tǒng)本身所能承受的用戶數(shù)、可用的網(wǎng)絡(luò)連接數(shù)或其它方面的一些方面都是有限制的。并且基于安全性的考慮,必須經(jīng)常給操作系統(tǒng)打上最新的補丁。
3.Tomcat與其它web服務(wù)器整合使用
雖然tomcat也可以作web服務(wù)器,但其處理靜態(tài)html的速度比不上apache,且其作為web服務(wù)器的功能遠不如apache,因此我們想把apache和tomcat集成起來,將html與jsp的功能部分進行明確分工,讓tomcat只處理jsp部分,其它的由apache,IIS等這些web服務(wù)器處理,由此大大節(jié)省了tomcat有限的工作“線程”。
4.負載均衡
在負載均衡的思路下,多臺服務(wù)器為對稱方式,每臺服務(wù)器都具有同等的地位,可以單獨對外提供服務(wù)而無須其他服務(wù)器的輔助。通過負載分擔(dān)技術(shù),將外部發(fā)送來的請求按一定規(guī)則分配到對稱結(jié)構(gòu)中的某一臺服務(wù)器上,而接收到請求的服務(wù)器都獨立回應(yīng)客戶機的請求。
提供服務(wù)的一組服務(wù)器組成了一個應(yīng)用服務(wù)器集群(cluster),并對外提供一個統(tǒng)一的地址。當(dāng)一個服務(wù)請求被發(fā)至該集群時,根據(jù)一定規(guī)則選擇一臺服務(wù)器,并將服務(wù)轉(zhuǎn)定向給該服務(wù)器承擔(dān),即將負載進行均衡分攤。
通過應(yīng)用負載均衡技術(shù),使應(yīng)用服務(wù)超過了一臺服務(wù)器只能為有限用戶提供服務(wù)的限制,可以利用多臺服務(wù)器同時為大量用戶提供服務(wù)。當(dāng)某臺服務(wù)器出現(xiàn)故障時,負載均衡服務(wù)器會自動進行檢測并停止將服務(wù)請求分發(fā)至該服務(wù)器,而由其他工作正常的服務(wù)器繼續(xù)提供服務(wù),從而保證了服務(wù)的可靠性。
負載均衡實現(xiàn)的方式大概有四種:第一是通過DNS,但只能實現(xiàn)簡單的輪流分配,不能處理故障,第二如果是基于MS IIS,Windows 2003 server本身就帶了負載均衡服務(wù),第三是硬件方式,通過交換機的功能或?qū)iT的負載均衡設(shè)備可以實現(xiàn),第四種是軟件方式,通過一臺負載均衡服務(wù)器進行,上面安裝軟件。使用Apache Httpd Server做負載平衡器,Tomcat集群節(jié)點使用Tomcat就可以做到以上第四種方式。這種方式比較靈活,成本相對也較低。另外一個很大的優(yōu)點就是可以根據(jù)應(yīng)用的情況和服務(wù)器的情況采取一些策略。
本節(jié)將向您詳細介紹一些加速可使Tomcat實例加速運行的技巧和方法,無論是在什么操作系統(tǒng)或者何種Java虛擬機上。在有些情況下,您可能沒有控制部署環(huán)境上的操作系統(tǒng)或者Java虛擬機。在這種情況下,您就需要逐行了解以下的的一些建議,然而你應(yīng)該在修改后使之生效。我認為以下方法是Tomcat性能自身調(diào)整的最佳方式。
1.禁用DNS查詢
當(dāng)web應(yīng)用程序向要記錄客戶端的信息時,它也會記錄客戶端的IP地址或者通過域名服務(wù)器查找機器名轉(zhuǎn)換為IP地址。DNS查詢需要占用網(wǎng)絡(luò),并且包括可能從很多很遠的服務(wù)器或者不起作用的服務(wù)器上去獲取對應(yīng)的IP的過程,這樣會消耗一定的時間。為了消除DNS查詢對性能的影響我們可以關(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"/>
除非你需要連接到站點的每個HTTP客戶端的機器名,否則我們建議在生產(chǎn)環(huán)境上關(guān)閉DNS查詢功能。可以通過Tomcat以外的方式來獲取機器名。這樣不僅節(jié)省了網(wǎng)絡(luò)帶寬、查詢時間和內(nèi)存,而且更小的流量會使日志數(shù)據(jù)也會變得更少,顯而易見也節(jié)省了硬盤空間。對流量較小的站點來說禁用DNS查詢可能沒有大流量站點的效果明顯,但是此舉仍不失為一良策。誰又見到一個低流量的網(wǎng)站一夜之間就流量大增呢?
2.調(diào)整線程數(shù)
另外一個可通過應(yīng)用程序的連接器(Connector)進行性能控制的的參數(shù)是創(chuàng)建的處理請求的線程數(shù)。Tomcat使用線程池加速響應(yīng)速度來處理請求。在Java中線程是程序運行時的路徑,是在一個程序中與其它控制線程無關(guān)的、能夠獨立運行的代碼段。它們共享相同的地址空間。多線程幫助程序員寫出CPU最大利用率的高效程序,使空閑時間保持最低,從而接受更多的請求。
Tomcat4中可以通過修改minProcessors和maxProcessors的值來控制線程數(shù)。這些值在安裝后就已經(jīng)設(shè)定為默認值并且是足夠使用的,但是隨著站點的擴容而改大這些值。minProcessors服務(wù)器啟動時創(chuàng)建的處理請求的線程數(shù)應(yīng)該足夠處理一個小量的負載。也就是說,如果一天內(nèi)每秒僅發(fā)生5次單擊事件,并且每個請求任務(wù)處理需要1秒鐘,那么預(yù)先設(shè)置線程數(shù)為5就足夠了。但在你的站點訪問量較大時就需要設(shè)置更大的線程數(shù),指定為參數(shù)maxProcessors的值。maxProcessors的值也是有上限的,應(yīng)防止流量不可控制(或者惡意的服務(wù)攻擊),從而導(dǎo)致超出了虛擬機使用內(nèi)存的大小。如果要加大并發(fā)連接數(shù),應(yīng)同時加大這兩個參數(shù)。web server允許的最大連接數(shù)還受制于操作系統(tǒng)的內(nèi)核參數(shù)設(shè)置,通常Windows是2000個左右,Linux是1000個左右。
在Tomcat5對這些參數(shù)進行了調(diào)整,請看下表:
屬性名 | 描述 |
maxThreads | Tomcat使用線程來處理接收的每個請求。這個值表示Tomcat可創(chuàng)建的最大的線程數(shù)。 |
acceptCount | 指定當(dāng)所有可以使用的處理請求的線程數(shù)都被使用時,可以放到處理隊列中的請求數(shù),超過這個數(shù)的請求將不予處理。 |
connnectionTimeout | 網(wǎng)絡(luò)連接超時,單位:毫秒。設(shè)置為0表示永不超時,這樣設(shè)置有隱患的。通常可設(shè)置為30000毫秒。 |
minSpareThreads | Tomcat初始化時創(chuàng)建的線程數(shù)。 |
maxSpareThreads | 一旦創(chuàng)建的線程超過這個值,Tomcat就會關(guān)閉不再需要的socket線程。 |
最好的方式是多設(shè)置幾次并且進行測試,觀察響應(yīng)時間和內(nèi)存使用情況。在不同的機器、操作系統(tǒng)或虛擬機組合的情況下可能會不同,而且并不是所有人的web站點的流量都是一樣的,因此沒有一刀切的方案來確定線程數(shù)的值。
當(dāng)?shù)谝淮卧L問一個JSP文件時,它會被轉(zhuǎn)換為Java serverlet源碼,接著被編譯成Java字節(jié)碼。你可以控制使用哪個編譯器,默認情況下,Tomcat使用使用命令行javac進行使用的編譯器。也可以使用更快的編譯器,但是這里我們將介紹如何優(yōu)化它們。
另外一種方法是不要把所有的實現(xiàn)都使用JSP頁面,而是使用一些不同的java模板引擎變量。顯然這是一個跨越很大的決定,但是事實證明至少這種方法是只得研究的。如果你想了解更多有關(guān)在Tomcat可使用的模板語言,你可以參考Jason Hunter和William Crawford合著的《Java Servlet Programming 》一書(O'Reilly公司出版)。
在Tomcat 4.0中可以使用流行而且免費的Jikes編譯器。Jikes編譯器的速度要由于Sun的Java編譯器。首先要安裝Jikes(可訪問http://oss.software.ibm.com/pub/jikes 獲得更多的信息),接著需要在環(huán)境變量中設(shè)置JIKESPATH包含系統(tǒng)運行時所需的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í)行。這聽起來有一點點奇怪,但這正是Ant有意為之的一部分,有一個API文檔指導(dǎo)開發(fā)者在沒有啟動一個新的JVM的情況下,使用Ant。這是使用Ant進行Java開發(fā)的一大優(yōu)勢。另外,這也意味著你現(xiàn)在能夠在Ant中使用任何javac支持的編譯方式,這里有一個關(guān)于Apache Ant使用手冊的javac page列表。使用起來是容易的,因為你只需要在 元素中定義一個名字叫“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>
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 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頁面在第一次使用時已經(jīng)被編譯,那么你可能希望在更新新的jsp頁面后馬上對它進行編譯。實際上,這個過程完全可以自動化,因為可以確認的是新的JSP頁面在生產(chǎn)服務(wù)器和在測試服務(wù)器上的運行效果是一樣的。
在Tomcat4的bin目錄下有一個名為jspc的腳本。它僅僅是運行翻譯階段,而不是編譯階段,使用它可以在當(dāng)前目錄生成Java源文件。它是調(diào)試JSP頁面的一種有力的手段。
可以通過瀏覽器訪問再確認一下編譯的結(jié)果。這樣就確保了文件被轉(zhuǎn)換成serverlet,被編譯了可直接執(zhí)行。這樣也準確地模仿了真實用戶訪問JSP頁面,可以看到給用戶提供的功能。也抓緊這最后一刻修改出現(xiàn)的bug并且修改它J
Tomcat提供了一種通過請求來編譯JSP頁面的功能。例如,你可以在瀏覽器地址欄中輸入http://localhost:8080/examples/jsp/dates/date.jsp?jsp_precompile=true,這樣Tomcat就會編譯data.jsp而不是執(zhí)行它。此舉唾手可得,不失為一種檢驗頁面正確性的捷徑。
4. 其它
前面我們提到過操作系統(tǒng)通過一些限制手段來防止惡意的服務(wù)攻擊,同樣Tomcat也提供了防止惡意攻擊或禁止某些機器訪問的設(shè)置。
Tomcat提供了兩個參數(shù)供你配置:RemoteHostValve 和RemoteAddrValve。
通過配置這兩個參數(shù),可以讓你過濾來自請求的主機或IP地址,并允許或拒絕哪些主機/IP。與之類似的,在Apache的httpd文件里有對每個目錄的允許/拒絕指定。
例如你可以把Admin Web application設(shè)置成只允許本地訪問,設(shè)置如下:
<Context path="/path/to/secret_files" ...>
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127.0.0.1" deny=""/>
</Context>
如果沒有給出允許主機的指定,那么與拒絕主機匹配的主機就會被拒絕,除此之外的都是允許的。與之類似,如果沒有給出拒絕主機的指定,那么與允許主機匹配的主機就會被允許,除此之外的都是拒絕的。
?
?Tomcat容量計劃
以下介紹針對Tomcat做容量計劃的步驟:
1) 量化負載。如果站點已經(jīng)建立并運行,可以使用前面介紹的工具模仿用戶訪問,確定資源的需求量。
2) 針對測試結(jié)果或測試過程中進行分析。需要知道那些請求造成了負載過重或者使用過多的資源,并與其它請求做比較,這樣就確定了系統(tǒng)的瓶頸所在。例如:如果servlet在查詢數(shù)據(jù)庫的步驟上耗用較長的時間,那么就需要考慮使用緩沖池來降低響應(yīng)時間。
3) 確定性能最低標準。例如,你不想讓用戶花20秒來等待結(jié)果頁面的返回,也就是說甚至在達到訪問量的極限時,用戶等待的時間也不能超過20秒種(從點擊鏈接到看到返第一條返回數(shù)據(jù))。這個時間中包含了數(shù)據(jù)庫查詢時間和文件訪問時間。同類產(chǎn)品性能在不同的公司可能有不同的標準,一般最好采取同行中的最低標準或?qū)@個標準做出評估。
4) 確定如何合理使用底層資源,并逐一進行測試。底層資源包括CPU、內(nèi)存、存儲器、帶寬、操作系統(tǒng)、JVM等等。在各種生產(chǎn)環(huán)境上都按順序進行部署和測試,觀察是否符合需求。在測試Tomcat時盡量多采用幾種JVM,并且調(diào)整JVM使用內(nèi)存和Tomcat線程池的大小進行測試。同時為了達到資源充分合理穩(wěn)定地使用的效果,還需針對測試過程中出現(xiàn)的硬件系統(tǒng)瓶頸進行處理確定合理的資源配置。這個過程最為復(fù)雜,而且一般由于沒有可參考的值所以只能靠理論推斷和經(jīng)驗總結(jié)。
5) 如果通過第4步的反復(fù)測試如果達到了最優(yōu)的組合,就可以在相同的生產(chǎn)環(huán)境上部署產(chǎn)品了。
此外應(yīng)牢記一定要文檔化你的測試過程和結(jié)果,因為此后可能還會進行測試,這樣就可以拿以前的測試結(jié)果做為參考。另外測試過程要反復(fù)多次進行,每次的條件可能都不一樣,因此只有記錄下來才能進行結(jié)果比較和最佳條件的選擇。
這樣我們通過測試找到了最好的組合方式,各種資源得到了合理的配置,系統(tǒng)的性能得到了極大的提升。
?附加資料
很顯然本文也很難全面而詳盡地闡述性能優(yōu)化過程。如果你進行更多研究的話可能會把性能調(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性能測試資料及工具
1) Jmeter Wiki首頁,Jmeter為一個開源的100%Java開發(fā)的性能測試工具
http://wiki.apache.org/jakarta-jmeter/
2) Apache Benchmark使用說明
http://httpd.apache.org/docs-2.0/programs/ab.html
3) 一些Java相關(guān)測試工具的介紹,包含可以與Tomcat集成進行測試的工具
http://blog.csdn.net/wyingquan/
4) LoadRunner? 是一種預(yù)測系統(tǒng)行為和性能的工業(yè)標準級負載測試工具。它通過模擬數(shù)據(jù)以千萬計用戶來實施并發(fā)負載來對整個企業(yè)架構(gòu)進行測試,來幫助您更快的查找和發(fā)現(xiàn)問題。
http://www.mercury.com/us/products/performance-center/loadrunner/
2. 文中介紹的相關(guān)內(nèi)容的介紹
1) Apache 2.x + Tomcat 4.x做負載均衡,描述了如何利用jk配置集群的負載均衡。
http://raibledesigns.com/tomcat/index.html
2) 容量計劃的制定,收集了許多有關(guān)制定web站點容量計劃的例子:
http://www.capacityplanning.com/
3) 評測Tomcat5負載平衡與集群,
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) 性能測試工具之研究,介紹了性能測試工具的原理與思路
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) 詳細講解性能中數(shù)據(jù)庫集群的問題
http://www.theserverside.com/articles/article.tss?l=DB_Break
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=646524