前 言 隨著近來J2EE軟件廣泛地應(yīng)用于各行各業(yè),系統(tǒng)調(diào)優(yōu)也越來越引起軟件開發(fā)者和應(yīng)用服務(wù)器提供商的重視。而對于最終客戶來說,在一個高效、穩(wěn)定地實現(xiàn)他們的業(yè)務(wù)需求已經(jīng)是他們的基本要求。所以J2EE調(diào)優(yōu)顯得非常重要,而BEA WebLogic Server是業(yè)界領(lǐng)先的應(yīng)用服務(wù)器,BEA WebLogic平臺下的J2EE調(diào)優(yōu)也就尤為重要,她將為我們提供普遍的J2EE調(diào)優(yōu)方案。最近網(wǎng)絡(luò)、雜志上的J2EE調(diào)優(yōu)文章層出不窮。本人也將自己平時工作中的一些經(jīng)驗積累分享給大家,拋磚引玉。 本文從J2EE應(yīng)用架構(gòu)(下圖)來分別剖析系統(tǒng)調(diào)優(yōu),首先我們一般會從應(yīng)用程序出發(fā),去審核代碼,做到代碼級的優(yōu)化,然后再調(diào)整應(yīng)用服務(wù)器(BEA WebLogic8.1)和數(shù)據(jù)庫 (Oracle9i)的參數(shù),最后當然是調(diào)整操作系統(tǒng)和網(wǎng)絡(luò)的性能(包括硬件升級)。誠然,在我遇到的很多項目中,都是出現(xiàn)了性能問題后才想到調(diào)優(yōu),而且一般都是先進行系統(tǒng)參數(shù)調(diào)整,實在解決不了才會對代碼進行檢查.實際上,我們應(yīng)當將代碼級的調(diào)優(yōu)放在應(yīng)用設(shè)計時來做,測試生產(chǎn)時修改代碼將是一件極其痛苦的事情。 第一章 應(yīng)用程序調(diào)優(yōu) 1.1.1 通用代碼調(diào)優(yōu) 1.1.2 減小沒有必要的操作 對象的創(chuàng)建是個很昂貴的工作,所以我們應(yīng)當盡量減少對象的創(chuàng)建,在需要的時候聲明它,初 始化它,不要重復(fù)初始化一個對象,盡量能做到再使用,而用完后置null有利于垃圾收集。讓類實現(xiàn)Cloneable接口,同時采用工廠模式,將減少類的創(chuàng)建,每次都是通過clone()方法來獲得對象。另外使用接口也能減少類的創(chuàng)建。對于成員變量的初始化也應(yīng)盡量避免, 特別是在一個類派生另一個類時。 異常拋出對性能不利。拋出異常首先要創(chuàng)建一個新的對象。Throwable接口的構(gòu)造函數(shù)調(diào)用名為, fillInStackTrace()的本地(Native)方法,fillInStackTrace()方法檢查堆棧,收集調(diào)用跟蹤信息。只要有異常被拋出,VM就必須調(diào)整調(diào)用堆棧,因為在處理過程中創(chuàng)建了一個新的對象。 異常只能用于錯誤處理,不應(yīng)該用來控制程序流程。 此外, 建議關(guān)閉Debug輸出,盡量少用串行化、同步操作和耗時昂貴的服務(wù)(如Date())。 1.1.3 使用合適的類型 當原始類型不能滿足我們要求時,使用復(fù)雜類型。String和StringBuffer的區(qū)別自不必說了,是我們使用最多的類型,在涉及到字符運算時,強烈建議使用StringBuffer。在做String匹配時使用intern()代替equal()。 帶有final修飾符的類是不可派生的, 如果指定一個類為final,則該類所有的方法都是final。 Java編譯器會尋找機會內(nèi)聯(lián)所有的final方法,這將能夠使性能平均提高50%。類的屬性和方式使用final或者static修飾符也是有好處的。 調(diào)用方法時傳遞的參數(shù)以及在調(diào)用中創(chuàng)建的臨時變量都保存在棧(Stack)中,速度較快。所以盡量使用局部變量。 ArrayList和Vector,HashMap和Hashtable是我們經(jīng)常用到的類,前者不支持同步,后者支持同步,前者性能更好,大多數(shù)情況下選擇前者。 1.1.4 盡量使用pool,buffer和cache 使用pool、buffer和cache能大大提高系統(tǒng)的性能,這在J2EE的大部分技術(shù)中都是適用的。 在WebLogic中就大量使用了池:JDBC Connection Pool、Socket Pool、Object Pool和Thread Pool。I/O操作中,buffer是必須的,特別是對大文件的操作,不然容易造成內(nèi)存溢出。字節(jié)操作最快,所以盡可能采用write(byte[]),Buffered FileOutputStream比Buffered FileWriter要快,因為FileWriter需要Unicode到Byte的轉(zhuǎn)換。 而后面講到的JDBC、JSP、EJB和JMS我們都非常建議使用buffer和cache。為HttpServletResponse設(shè)置buffersize,使用wl-cache,緩存在JNDI樹上獲取的對象等等。 此外,使用JDK 1.4的非阻塞I/O對性能也有很大提高。 1.2 JDBC代碼調(diào)優(yōu) 1.2.1 嚴格資源使用 JDBC代碼調(diào)優(yōu)最大的原則就是使用WebLogic的連接池,而不是自己直連數(shù)據(jù)庫。在我接觸的很多自己實現(xiàn)連接池的項目中,大部分遇到死鎖和連接泄漏的問題,最后得不得修改代碼。而WebLogic提供了功能強大,性能良好的數(shù)據(jù)庫連接池,我們要做的只是封裝一個連接管理類,從JNDI樹上獲取數(shù)據(jù)源并緩存,得到連接,并提供一系列關(guān)閉數(shù)據(jù)庫資源的方法。 對任何資源使用的原則是用完即關(guān),不管是數(shù)據(jù)庫資源、上下文環(huán)境,還是文件。數(shù)據(jù)庫資源的泄漏極易造成內(nèi)存泄漏,乃至系統(tǒng)崩潰。在使用完數(shù)據(jù)庫資源后依次關(guān)閉ResultSet,Statement和Connection,而在一個數(shù)據(jù)庫連接多次進行數(shù)據(jù)庫操作時要特別注意ResultSet和Statement依次關(guān)閉。
try{ //open connection pstmt =conn.prepareStatement(strSql1); pstmt.executeUpdate(); pstmt.close(); pstmt =conn.prepareStatement(strSql2); rs=pstmt.executeQuery(); while (rs.next()){ //process } rs.close(); pstmt.close(); }catch(Exception e){ //close rs,psmt,con }finally{ //close rs,psmt,con } 1.2.2 實用技巧 在JDBC操作中還有一些小的技巧跟大家分享:由于獲取連接時默認自動提交方式,使用connection.setAutoCommit(false)關(guān)閉自動提交,使用PreparedStatement,批量更新,業(yè)務(wù)復(fù)雜或者大數(shù)據(jù)量操作時使用存儲過程,盡量使用RowSet,此外設(shè)置記錄集讀取緩存FetchSize和設(shè)置記錄集讀取方向FetchDirection對性能也有一定的提高。 1.2.3 優(yōu)化SQL語句 SQL語句的優(yōu)化牽涉到很多數(shù)據(jù)庫的知識,需要與索引配合,因此需要DBA對代碼中的SQL進行檢查測試。常見的,select *不提倡使用,效率極差,建議顯式獲取列,即使是所有字段也應(yīng)羅列,而取總數(shù)時使用count(*),為提高cache的命中率,盡量做到SQL重用。對于大數(shù)據(jù)量的查詢,可以充分利用Oracle數(shù)據(jù)庫的特性,每次取出m-n行的數(shù)據(jù),實現(xiàn)分頁查詢。另外,提高性能的好選擇可能就是把所有的字符數(shù)據(jù)都保存為Unicode,Java以Unicode形式處理所有數(shù)據(jù),因此,數(shù)據(jù)庫驅(qū)動程序不必再執(zhí)行轉(zhuǎn)換過程。 1.3 Web代碼調(diào)優(yōu) 1.3.1 HttpSession的使用 應(yīng)用服務(wù)器保存很多會話時,容易造成內(nèi)存不足,所以盡量減少session的使用,放置session 里的對象不應(yīng)該是大對象,最好是簡單小對象,實現(xiàn)串行化接口。當會話不再需要時,應(yīng)當及時調(diào)用invalidate()方法清除會話。而當某個變量不需要時,及時調(diào)用removeAttribute()方法清除變量。請勿將EJB對象放置在session中。 1.3.2 JSP代碼調(diào)優(yōu) 目前,在JSP頁面中引入外部資源的方法主要有兩種:include指令,以及include動作。 include指令:例如<%@ include file="copyright.html" %>,該指令在編譯時引入指定的資源。在編譯之前,帶有include指令的頁面和指定的資源被合并成一個文件。被引用的外部資源在編譯時就確定,比運行時才確定資源更高效。 include動作:例如<jsp:include page="copyright.jsp" />。該動作引入指定頁面執(zhí)行后生成的結(jié)果。由于它在運行時完成,因此對輸出結(jié)果的控制更加靈活。但是,只有當被引用的內(nèi)容頻繁地改變時,或者在對主頁面的請求沒有出現(xiàn)之前,被引用的頁面無法確定時,使用include動作才合算。 對于那些無需跟蹤會話狀態(tài)的jsp,關(guān)閉自動創(chuàng)建的會話可以節(jié)省一些資源。使用如下page指令: <%@ page session="false"%> ;盡量不要將JSP頁面定義為單線程,應(yīng)設(shè)置為<%@page isThreadSafe=”true”%>;在JSP頁面最好使用輸出緩存功能,如: <%@page buffer="32kb"%>;盡量用wl:cache定制標記來緩存靜態(tài)或相對靜態(tài)的內(nèi)容,緩存jsp:include操作的結(jié)果能顯著提高應(yīng)用程序的運行性能。 1.3.3 Servlet代碼調(diào)優(yōu) Servlet代碼調(diào)優(yōu)比較簡單:在Servlet之間跳轉(zhuǎn)時,forward比sendRedirect更有效;設(shè)置HttpServletResponse 緩沖區(qū),如:response.setBufferSize(20000);在init()方法里緩存靜態(tài)數(shù)據(jù),而在destroy()中釋放它;建議在Servlet里使用ServletOutputStream輸出圖片等對象;避免在Servlet和Jsp中定界事務(wù)等。 1.4 JMS代碼調(diào)優(yōu) 1.4.1 注意必要的事項,避免使用不必要的特征 JMS提供了強有力的消息處理機制,但是為了最大限度的提高JMS系統(tǒng)的性能,應(yīng)避免使用不需要使用的特征,同時也要注意必要的事項。比如:盡量使用接收程序能直接使用的最簡單、最小的消息類型;消息選擇器要盡可能簡單(最好不使用),盡量不要使用復(fù)雜的操作符,如like、in或者between等,使用字符串數(shù)據(jù)類型的速度最慢;務(wù)必為特定的應(yīng)用程序定義特定的JMS連接工廠,并且禁用默認的JMS連接工廠;不要在javax.*與weblogic.*的名字空間中使用JNDI名稱;盡量使用異步消費者,線程不必封鎖以等待消息的到達;使用完JNDI樹上的資源后注意關(guān)閉。 1.4.2 消息類型的選擇 標準JMS提供了五種消息類型,而TextMessage應(yīng)用最為普遍, 當發(fā)送的消息是幾種原始數(shù)據(jù)類型的集合體時,最好使用MapMessage消息類型,而不要使用ObjectMessage,以便減少不同系統(tǒng)間的耦合。此外消息是否使用壓縮要慎重考慮,壓縮未必能減少消息大小。如果生產(chǎn)者、消費者和目的地并置在同一WebLogic Server內(nèi)部,通常不使用壓縮。WebLogic特有的XMLMessage能為運行于消息主體之上的消息選擇器提供內(nèi)嵌式支持,而且易于數(shù)據(jù)交換。因此,建議應(yīng)用程序之間傳送消息使用XML消息格式,而應(yīng)用程序內(nèi)部間傳送消息使用二進制消息格式。 1.4.3 確認方式的選擇和JMS事務(wù) 使用事務(wù)性會話時,盡量使用恰當?shù)南⒋_認方式:如果需求允許,使用NO_ACKKNOWLEDGE;非持久的訂閱者使用DUPS_OK_ACKNOWLEDGE或者MULTICAST_NO_ACKNOWLEDGE。而使用JTA的UserTransaction,確認方式將被忽略。在使用JMS事務(wù)時,無效的消息會導致事務(wù)的回滾,以致消息重發(fā)這樣的死循環(huán)。此時,可以將無效消息發(fā)送到錯誤消息隊列,并提交JMS事務(wù),這將確保消息不會再次傳遞。 1.5 EJB代碼調(diào)優(yōu) 1.5.1 有效使用設(shè)計模式 GoF 的《設(shè)計模式》為我們實現(xiàn)高性能、易擴展的J2EE應(yīng)用提供理論保障和技術(shù)支持。而EJB作為J2EE的核心組件和技術(shù),善用設(shè)計模式對系統(tǒng)性能影響很大。Service Locator 和Value Object 已為我們所熟悉,Floyd Marinescu的《EJB Design Patterns》中的Session Fa?ade、Message Fa?ade、EJB Command和Data Transfer Object等設(shè)計模式更是為我們提供設(shè)計典范:緩存對EJBHome的訪問;使用門面模式,不暴露Entity Bean,用Session Bean封裝Entity Bean;如果可以異步處理,則用MDB代替Session Bean;封裝業(yè)務(wù)邏輯在輕量級JavaBean中;使用值對象等簡單對象傳遞數(shù)據(jù);不直接使用get/set方法操作Entity Bean。當然過度使用模式或者牽強套用模式也是不提倡的,總的原則就是減少網(wǎng)絡(luò)流量,改進事務(wù)管理。 1.5.2 使用EJB和WebLogic的特性 使用EJB和WebLogic的新特性往往能提高性能。與EJB2.0特性相關(guān)的技巧有:一個Application中使用本地接口,對于Entity Bean肯定使用本地接口,避免遠程調(diào)用的開銷;使用CMP管理關(guān)系,而不是BMP,EJB2.0中CMP的性能大大改善,性能和移植性都優(yōu)于BMP;使用ejbSelect進行內(nèi)部查詢;使用home方法進行外部查詢和批處理; 數(shù)據(jù)庫驅(qū)動級聯(lián)刪除等。 與WebLogic特性相關(guān)的技巧有:使用自動生成主鍵,WebLogic為Oracle和Sqlserver兩種數(shù)據(jù)庫的CMP提供了自動生成主鍵功能,節(jié)約了Entity Bean產(chǎn)生主鍵的時間,同時設(shè)key-cache-size不小于100;WebLogic管理事務(wù)性能更好,使用容器管理,而不是Bean管理事務(wù);WebLogic提供了為CMP動態(tài)查詢和批量插入功能,對性能也有很大幫助。 1.5.3 緩存資源 對SLSB或者MDB來說,使用setMesssageDrivenContext()或者ejbCreate()方法緩存特定資源,在ejbRemove()方法里釋放; 對SLSB或者MDB來說,使用setSessionContext()或者ejbCreate()方法緩存特定資源,在ejbRemove()方法里釋放;對Entity Bean來說,使用setEntityContext ()方法緩存特定資源,在unSetEntityContext ()方法里釋放。 1.5.4 如何選擇和使用Entity Bean 1. 在設(shè)計EJB時,要適當考慮EJB的粒度, 細粒度的EJB在事務(wù)管理和資源管理的開銷太大,盡量創(chuàng)建粗粒度的 EJB , 不要太粗,粗到能滿足實際需求就可以; 2. Entity Bean不是唯一方式,如果只有一個很小的數(shù)據(jù)子集被經(jīng)常改變,建議采用JDO; 3. 在操作大數(shù)據(jù)量的時候,直接采用JDBC比Entity Bean更有效; 4. 避免采用返回很大數(shù)據(jù)組的finder方法,如 FindAll() 方法,因為它的實現(xiàn)代價太大; 5. 考慮設(shè)置域組field groups,減少沒有必要并昂貴的屬性加載,如BLOB; 6. 對于EJB1.1或者BMP,可以設(shè)置is-modified-method-name屬性,根據(jù)isModified()的值來判斷是否調(diào)用ejbStore()等方法,減少沒有必要運算; 7. 避免連接多個表創(chuàng)建BMP,可以使用視圖,存儲過程或者O/R Mapping等方式。 1.5.5 其他的一些小技巧 1. 考慮使用 javax.ejb.SessionSynchronization 接口,提供在Rollback之后恢復(fù)數(shù)據(jù)的方法: afterBegin(), beforeCompletion(), afterCompletion(); 2. 使用完SFSB之后,調(diào)用remove()方法釋放實例; 3. 假如你不需要EJB服務(wù)的時候,建議使用普通Java類; 4. 避免EJB之間相互調(diào)用; 5. 使用多讀模式。 第二章 應(yīng)用服務(wù)器調(diào)優(yōu) 2.1 JVM調(diào)優(yōu) 2.1.1 垃圾收集和堆大小 垃圾收集(GC)是指JVM釋放Java堆中不再使用的對象所占用的內(nèi)存的過程,而Java堆(Heap)是指Java應(yīng)用程序?qū)ο笊娴目臻g。堆大小決定了GC的頻度和時間。堆越大,GC頻度低,速度慢。堆越小,GC頻度高,速度快。所以GC和堆大小是一組矛盾。為了獲取理想的Heap堆大小,需要使用-verbosegc參數(shù)(Sun jdk: -Xloggc:<file>)以打開詳細的GC輸出。分析GC的頻度和時間,結(jié)合應(yīng)用最大負載所需內(nèi)存情況,得出堆的大小。 通常情況下,我們建議使用可用內(nèi)存(除操作系統(tǒng)和其他應(yīng)用程序占用之外的內(nèi)存)70-80%,為避免堆大小調(diào)整引起的開銷,設(shè)置內(nèi)存堆的最小值等于最大值即:-Xms=-Xmx。而為了防止內(nèi)存溢出,建議在生產(chǎn)環(huán)境堆大小至少為256M(Platform至少512M),實際環(huán)境中512M~1G左右性能最佳,2G以上是不可取的,在調(diào)整內(nèi)存時可能需要調(diào)整核心參數(shù)進程的允許最大內(nèi)存數(shù)。對于sun和hp的jvm,永久域太小(默認4M)也可能造成內(nèi)存溢出,應(yīng)增加參-XX:MaxPermSize=128m。建議設(shè)置臨時域-Xmn的大小為-Xmx的1/4~1/3, SurvivorRatio為8。 為了獲得更好的性能,建議在啟動文件設(shè)置WebLogic為產(chǎn)品模式,此時sun和hp jvm JIT引擎為-server,默認情況下打開JIT編譯模式對性能也有幫助。調(diào)整Chunk Size和Chunk Pool Size也可能對系統(tǒng)的吞吐量有提高。此外還需關(guān)閉顯示GC: -XX:+DisableExplicitGC。 當然在Intel平臺上使用jRockit(使用參數(shù)-jrockit)無疑大大提高WebLogic性能。 2.1.2 jRockit調(diào)優(yōu) jRockit支持四種垃圾收集器:分代復(fù)制收集器、單空間并發(fā)收集器、分代并發(fā)收集器和并行收集器。默認狀態(tài)下,JRockit使用分代并發(fā)收集器。要改變收集器,可使用-Xgc:<gc-name>,對應(yīng)四個收集器分其他為gencopy, singlecom, gencon以及parallel。為得到更好的響應(yīng)性能,應(yīng)該使用并發(fā)垃圾回收器:-Xgc:gencon,可使用-Xms和-Xmx設(shè)置堆棧的初始大小和最大值,要設(shè)置護理域-Xns為-Xmx的10%。而如果要得到更好的性能,應(yīng)該選用并行垃圾回收器:-Xgc: parallel,由于并行垃圾回收器不使用nursery,不必設(shè)置-Xns。 如果你的線程大于100或者在linux平臺下,可以嘗試使用瘦線程模式:-Xthinthread,同時關(guān)閉Native IO:-Xallocationtype:global。 jRockit 還提供了強大的圖形化監(jiān)控工具Jrockit Management Console。欲詳細了解JRockit可訪問:http://edocs.bea.com/wljrockit/docs81/index.html。 2.2 Server調(diào)優(yōu) WebLogic Server的核心組件由監(jiān)聽線程,套接字復(fù)用器和可執(zhí)行線程的執(zhí)行隊列組成。當服務(wù)器由監(jiān)聽線程接收到連接請求后,將對它的連接控制權(quán)交給等待接收請求的套接字復(fù)用器。然后套接字復(fù)用器讀取離開套接字的請求,并將此請求及相關(guān)安全信息或事務(wù)處理環(huán)境一起置入適當?shù)膱?zhí)行隊列中(一般為默認的執(zhí)行隊列)。 當有一個請求出現(xiàn)在執(zhí)行隊列中時,就會有一個空閑的執(zhí)行線程從該隊列中取走發(fā)來的該請求,并返回應(yīng)答,然后等待下一次請求。因此要提高WebLogic的性能,就必須從調(diào)整核心組件性能出發(fā)。 2.2.1 盡量使用本地I/O庫 WebLogic Server有兩套套接字復(fù)用器:Java版和本地庫。采用小型本地庫更有效,盡量激活Enable Native IO(默認),此時UNIX默認使用CPUs+1個線程,Window下為雙倍CPU。如果系統(tǒng)不能加載本地庫,將會拋出java.lang.UnsatisfiedLinkException,此時只能使用Java套接字復(fù)用器,可以調(diào)整socket readers 百分比,默認為33%。該參數(shù)可以在Console Server Tuning Configuration配置欄里設(shè)置。 2.2.2 調(diào)整默認執(zhí)行線程數(shù) 理想的默認執(zhí)行線程數(shù)是由多方面的因素決定的,比如機器CPU性能、總線體系架構(gòu)、I/O、操作系統(tǒng)的進程調(diào)度機制、JVM的線程調(diào)度機制。WebLogic生產(chǎn)環(huán)境下默認的線程為25個,隨著CPU個數(shù)的增加,WebLogic可以近乎線性地提高線程數(shù)。線程數(shù)越多,花費在線程切換的時間也就越多,線程數(shù)越小,CPU可能無法得到充分利用。為獲取一個理想的線程數(shù),需要經(jīng)過反復(fù)的測試。在測試中,可以以25*CPUs為基準進行調(diào)整。當空閑線程較少,CPU利用率比較低時,可以適當增加線程數(shù)的大小(每五個遞增)。對于PC Server 和Window 2000,則最好每個CPU小于50個線程, 以CPU利用率為90%左右為佳。由于目前WebLogic執(zhí)行線程沒有縮小線程數(shù)的功能,所以應(yīng)將參數(shù)Threads Increase設(shè)置為0,同時不應(yīng)改變優(yōu)先級的大小。 2.2.3 調(diào)整連接參數(shù) WebLogic Server用Accept Backlog參數(shù)規(guī)定服務(wù)器向操作系統(tǒng)請求的隊列大小,默認值為50。當系統(tǒng)重載負荷時,這個值可能過小,日志中報Connection Refused,導致有效連接請求遭到拒絕,此時可以提高Accept Backlog 25%直到連接拒絕錯誤消失。對于Portal類型的應(yīng)用,默認值往往是不夠的。Login Timeout和SSL Login Timeout參數(shù)表示普通連接和SSL連接的超時時間,如果客戶連接被服務(wù)器中斷或者SSL容量大,可以嘗試增加該值。這些參數(shù)可以在Console Server Tuning Configration配置欄里找到。 2.2.4 創(chuàng)建新的執(zhí)行隊列 創(chuàng)建新的執(zhí)行隊列有助于解決核心業(yè)務(wù)優(yōu)先、避免交叉阻塞、死鎖和長時間處理的業(yè)務(wù)等問題。通常會將自己的執(zhí)行隊列和默認的執(zhí)行隊列設(shè)置不同的優(yōu)先級,這里優(yōu)先級不應(yīng)設(shè)為9或者10。 定義一個新的執(zhí)行隊列很容易,利用View Excute Queue選項中的Configure a new Excute Queue鏈接即可定制新的執(zhí)行隊列。創(chuàng)建新的執(zhí)行隊列后,用戶需要為應(yīng)用程序的J2EE組件配置分配策略,以便它可以找到新的隊列。舉個例子:要將servlet或jsp捆綁到一個特定的執(zhí)行隊列,必須替換web.xml文件項,將wl-dispatch-policy初始化參數(shù)設(shè)置為自己的執(zhí)行隊列名。
<servlet> <servlet-name>servletname</servlet-name> <jsp-file>/directoryname/deployment.jsp</jsp-file> <init-param> <param-name>wl-dispatch-policy</param-name> <param-value>NewExecuteQueueName</param-value> </init-param> </servlet> 我們可以為一個jsp或者servlet乃至一個WEB應(yīng)用設(shè)置自己的執(zhí)行隊列。同時也可以為EJB設(shè)置自己的執(zhí)行隊列。對于執(zhí)行時間比較長的MDB,建議使用自己的執(zhí)行隊列。 2.3 JDBC調(diào)優(yōu) 2.3.1 調(diào)整連接池配置 JDBC Connection Pool的調(diào)優(yōu)受制于WebLogic Server線程數(shù)的設(shè)置和數(shù)據(jù)庫進程數(shù),游標的大小。通常我們在一個線程中使用一個連接,所以連接數(shù)并不是越多越好,為避免兩邊的資源消耗,建議設(shè)置連接池的最大值等于或者略小于線程數(shù)。同時為了減少新建連接的開銷,將最小值和最大值設(shè)為一致。 增加Statement Cache Size對于大量使用PreparedStatement對象的應(yīng)用程序很有幫助,WebLogic能夠為每一個連接緩存這些對象,此值默認為10。在保證數(shù)據(jù)庫游標大小足夠的前提下,可以根據(jù)需要提高Statement Cache Size。比如當你設(shè)置連接數(shù)為25,Cache Size為10時,數(shù)據(jù)庫可能需要打開25*10=250個游標。不幸的是,當遇到與PreparedStatement Cache有關(guān)的應(yīng)用程序錯誤時,你需要將Cache Size設(shè)置為0。 盡管JDBC Connection Pool提供了很多高級參數(shù),在開發(fā)模式下比較有用,但大部分在生產(chǎn)環(huán)境下不需調(diào)整。這里建議最好不要設(shè)置測試表, 同時Test Reserved Connections和Test Released Connections也無需勾上。 當然如果你的數(shù)據(jù)庫不穩(wěn)定,時斷時續(xù),你就可能需要上述的參數(shù)打開。 最后提一下驅(qū)動程序類型的選擇,以O(shè)racle為例,Oracle提供thin驅(qū)動和oci驅(qū)動,從性能上來講,oci驅(qū)動強于thin驅(qū)動,特別是大數(shù)據(jù)量的操作。但在簡單的數(shù)據(jù)庫操作中,性能相差不大,隨著thin驅(qū)動的不斷改進,這一弱勢將得到彌補。而thin驅(qū)動的移植性明顯強于oci驅(qū)動。所以在通常情況下建議使用thin驅(qū)動。而最新驅(qū)動器由于WebLogic server/bin目錄下的類包可能不是最新的,請以O(shè)racle網(wǎng)站為準:http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc9201.html。 2.4 WEB調(diào)優(yōu) 2.4.1 調(diào)整WEB應(yīng)用描述符 WEB應(yīng)用除代碼之外的調(diào)優(yōu)比較簡單,僅僅是對一些WEB應(yīng)用描述符的調(diào)整。首先關(guān)閉Session Monitoring Enabled,僅僅在Cluster環(huán)境下設(shè)置Session復(fù)制(優(yōu)先使用內(nèi)存復(fù)制),在保證應(yīng)用正常運行的情況下,設(shè)置較短的Session超時時間。 同時生產(chǎn)環(huán)境下無需檢查Jsp和servlet:JSPPage Check Secs和Servlet Reload Check Secs均設(shè)為-1,關(guān)閉JSPKeep Generated 和JSPVerbose對性能也有幫助。此外,還可以對jsp進行預(yù)編譯,有兩種方法:激活precompile選項;使用weblogic.appc事先編譯,建議采用后者。 2.5 JMS調(diào)優(yōu) 1. 增加-Dweblogic.JMSThreadPoolSize=n(至少為5),以提高處理JMS的線程數(shù),在jRockit上增加-XXenablefatspin以減少加鎖沖突; 2. 采用文件存儲策略,將同步寫策略設(shè)置為Direct-Write,同時在windows平臺上啟用磁盤寫入緩存; 3. 使用分布式目的地時,激活連接工廠Load Balancing Enabled ,Server Affinity Enabled; 4. 為減少服務(wù)器不必要的JMS請求路由,如果多個目的地之間存在事務(wù),則部署在同一JMS服務(wù)器上,盡量將連接工廠部署到JMS服務(wù)器所在的WebLogic實例上,集群環(huán)境下,則最好將連接工廠部署到集群中的所有服務(wù)器上,而集群中每個JMS服務(wù)器和目的地成員盡量使用類似的設(shè)置; 5. 啟用消息分頁存儲功能,以釋放內(nèi)存,可以為JMS服務(wù)器和目的地設(shè)置, 激活Messages Paging Enabled和Bytes Paging Enabled,同時使用限額防止服務(wù)器耗盡接收消息的所有可用內(nèi)存空間; 6. 在運行WebLogic Server進程之外的生產(chǎn)者務(wù)必使用流控制, 并增大Send Timeout; 7. 將JMS Server Expiration Scan Interval設(shè)很大的值,能禁止主動掃描過期消息; 8. 使用FIFO或者LIFO方式處理目的地消息; 9. MDB的max-beans-in-free-pool不應(yīng)大于最大MDB線程數(shù)(默認線程數(shù)/2+1)。 6 EJB調(diào)優(yōu) 2.6.1 調(diào)整pool和cache initial-beans-in-free-pool定義SLSB啟動時實例的個數(shù),默認為0,可以調(diào)大到正常并發(fā)數(shù)的大小,以減少初始響應(yīng)時間。max-beans-in-free-pool為最大個數(shù),默認1000對SLSB來說,在頻繁創(chuàng)建和刪除實例的情況下很有幫助,一般不用調(diào)整,至少設(shè)為默認線程數(shù),過大容易造成內(nèi)存溢出。而對Entity Bean來說,由于是匿名的,所以當頻繁使用finder、home和create方法時可以調(diào)大。 對SFSB來說,盡量將max-beans-in-cache參數(shù)設(shè)置得足夠的大,以滿足Bean實例對最大并發(fā)用戶數(shù)的要求,可以避免有狀態(tài)會話Bean過多的鈍化行為。而idle-timeout-seconds盡量設(shè)置小,如果SFSB不用于存儲Web應(yīng)用會話狀態(tài)可以設(shè)置為0。 對于Entity Bean來說, max-beans-in-cache同樣可以首先采用默認值1000,監(jiān)控實例緩存和鈍化的情況,再做適當調(diào)整。 并行策略concurrency-strategy定義了實體Bean如何管理鎖,有四種策略: Exclusive、Databse、ReadOnly、Optimistic。效率依次提高,可靠性依次降低,盡量避免使用互斥策略,如果Bean無需更新操作,使用只讀策略,更甚的是,如果Bean的內(nèi)容不會改變,可設(shè)置read-timeout-seconds為0,樂觀并行策略時采用事務(wù)間緩存策略,在entity-cache描述符中將cache-between-transactions元素設(shè)為true。 對EJB組件來說,有四種事務(wù)隔離水平: 第三章 數(shù)據(jù)庫調(diào)優(yōu) 3.1.1 Oracle性能優(yōu)化 Oracle9i的性能優(yōu)化除了調(diào)整kernal之外就是主要對Oracle啟動文件的調(diào)整,即調(diào)整SGA的參數(shù)。注意,不同操作系統(tǒng)不同位數(shù)的機器最優(yōu)的參數(shù)不是一樣的,這里主要有windows和unix之分,32位和64位之分。 首先需要調(diào)大進程數(shù)和游標數(shù),一般默認的值對實際應(yīng)用來說都比較小,比如說,進程數(shù)可以調(diào)到300,游標數(shù)可以調(diào)到500。 其次,看一個經(jīng)驗公式: OS 使用內(nèi)存+ SGA + session*(sort_area_size + hash_area_size +2M)<0.7RAM,通常認為此時的SGA比較合理。這里sort_area_size為64k, hash_area_size為128k(當排序多的時候需要增大sort_area_size,按調(diào)整后的值計算),session表示最大并發(fā)進程數(shù),假設(shè)100個。假如1G內(nèi)存的機器,OS占用200M,PGA占用200M左右,那么SGA可以設(shè)為400-500M,如果2G內(nèi)存可以1G給 SGA,8G可以5G給SGA。不過對于32位數(shù)據(jù)庫來說,通常最多只能使用1.7G內(nèi)存。 然后,SGA內(nèi)參數(shù)設(shè)置的基本原則是: data buffer 通常可以盡可能的大,shared_pool_size 要適度,log_buffer 通常大到幾百K到1M就差不多。具體的:data buffer 1G內(nèi)存可以設(shè)置500M,2G設(shè)為1.2G,8G可設(shè)為5G 。shared_pool_size不易過大,通常應(yīng)該控制在200M--300M,如果使用了大量的存儲過程,可以根據(jù)SGA的值增大到500M,如果增大后命中率得不到提高,則增加是無益的。具體的:1G內(nèi)存可以設(shè)置100M,2G設(shè)為150M,8G可設(shè)為300M。如不使用Java, java_pool_size 10-20M即可。large_pool_size如果不設(shè)置MTS,在20M -30M 即可,假如設(shè)置 MTS,可以考慮為 session * (sort_area_size + 2M)。 最后,關(guān)于內(nèi)存的設(shè)置可根據(jù)statspack信息和v$system_event,v$sysstat,v$sesstat,v$latch 等view信息來考慮微調(diào)。 3.1.2 Oracle的其他調(diào)整 為了Oracle高效率的運行,除了上面提到的內(nèi)存因素之外,還有就是需要良好的數(shù)據(jù)庫設(shè)計:表、視圖、索引和日志的合理規(guī)劃和建立。I/O的性能也是重要因素,應(yīng)盡量減少頁交換和頁分配。此外,就是改善檢查點的效率。 第四章 操作系統(tǒng)調(diào)優(yōu) 4.1 操作系統(tǒng)調(diào)整 操作系統(tǒng)影響應(yīng)用程序運行性能的因素主要有:硬件的配置(CPU、內(nèi)存、硬盤等),核心參數(shù),TCP/IP參數(shù)以及補丁的情況等。這里對操作系統(tǒng)的優(yōu)化,除了更新最新的補丁程序以保證應(yīng)用程序正常運行之外,就是調(diào)整TCP/IP參數(shù),文件描述符,對于個別操作系統(tǒng)還有其他特別的參數(shù)調(diào)整。下面將依次介紹不同操作系統(tǒng)的情況,更多的信息請參考各操作系統(tǒng)的文檔。 4.1.1 HP-UX 對于HP-UX,你首先需要安裝Java Patch: http://www.hp.com/products1/unix/java/patches/index.html,然后需要確認下面文檔中的核心參數(shù)是否滿足(可以使用sam命令修改核心參數(shù)):http://e-docs.bea.com/platform/suppconfigs/configs81/hpux11_risc/81sp3.html#80105。 調(diào)整TCP參數(shù): ndd -set /dev/tcp tcp_conn_req_max 1024, 將偵聽隊列的最大允許長度調(diào)整到1024。 有時操作系統(tǒng)限制進程使用的最大內(nèi)存數(shù)小于你要配置的內(nèi)存大小,則需要調(diào)整該值。 讀者可以從http://docs.hp.com/hpux/onlinedocs/TKP-90203/TKP-90203.html了解更多的HP-UX調(diào)整建議。 4.1.2 Solaris 調(diào)整TCP的參數(shù),等待時間間隔tcp-time-wait-interval建議設(shè)置為60000ms: /usr/sbin/ndd ?set /dev/tcp tcp_time_wait_interval 60000; 其他參數(shù)調(diào)整如下: tcp_xmit_hiwat/tcp_recv_hiwat 131072 tcp_conn_req_max_q/tcp_conn_req_max_q0 16384 調(diào)整一個進程打開的文件描述符的數(shù)量:軟限制和硬限制以及散列表的大小,修改/etc/system文件: set tcp:tcp_conn_hash_size=32768 set rlim_fd_cur=8192 set rlim_fd_max=8192 更多的調(diào)整信息請查閱: http://docs.sun.com/db/doc/806-7009(Solaris9)。 4.1.3 AIX AIX用no命令調(diào)整TCP參數(shù),等待時間間隔tcp_timewait: no -o tcp_timewait=4,將tcp.timewait參數(shù)設(shè)置為4個15秒間隔,即1分鐘。運行no -a命令將顯示網(wǎng)絡(luò)當前的所有屬性值。由于UDP_SENDSPACE默認的緩存大小是8k,為減少I/O異常,需調(diào)整為32k: no -o udp_sendspace=32768。此外, 當WebLogic HTTP請求忙時,可以調(diào)整偵聽隊列的最大長somaxconn到8192(默認值是1024)。 更多信息:http://publib16.boulder.ibmo.com/pseries/en-us/aixbman/prftungd/prftungd.htm。 4.1.4 Linux 調(diào)整Linux系統(tǒng)使用sysctl命令修改TCP參數(shù)等待時間間隔:sysctl -w ip_ct_tcp_timeout_time_wait=60;調(diào)整打開文件的最大數(shù):在/etc/sysctl.conf文件中,添加: Fs.file-max=65535,然后運行sysctl -p;調(diào)整打開文件描述符最大數(shù)為8192:在/etc/security/limits.conf文件,添加:WebLogic hard nofile 8192(僅針對WebLogic用戶),然后在WebLogic啟動文件里運行ulimit-n 8192激活設(shè)置。 更多信息請查閱:http://ipsysctl-tutorial.frozentux.net/ipsysctl-tutorial.html。 4.1.5 Windows Windows系統(tǒng)的調(diào)整通過修改注冊表HKEY-LOCAL-MACHINESYSTEMCurrent ControlSetServices文件夾來完成。可以調(diào)整TcpipParameters子文件夾中的等待時間間隔時間 TcpTimedWaitDelay參數(shù)的值。偵聽隊列最大長度的默認值為15,為修改它,可在InetinfoParameters子目錄中創(chuàng)建 DWORD條目ListenBackLog。 此外,Windows2000的Service Pack(要求sp3以上)也會影響系統(tǒng)穩(wěn)定性: http://e-docs.bea.com/platform/suppconfigs/configs81/win2ksvr_as_data_pentium/81sp3.html。 第五章 性能監(jiān)控和性能分析 5.1 性能瓶頸 最后,介紹一下實際分析J2EE應(yīng)用性能的常用命令和工具。對于實現(xiàn)一個高性能的J2EE應(yīng)用來說,掌握了J2EE調(diào)優(yōu)的理論經(jīng)驗還是不夠的。掌握性能監(jiān)控,發(fā)現(xiàn)瓶頸和問題診斷才是保證J2EE系統(tǒng)持續(xù)高效運行的關(guān)鍵。 瓶頸指的是限值所有吞吐操作以及嚴重影響反應(yīng)時間的系統(tǒng)內(nèi)資源。在分布式系統(tǒng)內(nèi)尋找并糾正瓶頸是非常困難的,需要有經(jīng)驗的團隊來解決。瓶頸會發(fā)生在Web服務(wù)器上,程序代碼中,應(yīng)用服務(wù)器上,數(shù)據(jù)庫,操作系統(tǒng)或者網(wǎng)絡(luò),硬件上。經(jīng)驗表明,瓶頸很容易發(fā)生在如下地方:數(shù)據(jù)庫連接與隊列中;應(yīng)用服務(wù)器的程序代碼中;應(yīng)用服務(wù)器和Web服務(wù)器硬件上;網(wǎng)絡(luò)和TCP配置中。實際中可以著力對這些環(huán)節(jié)進行監(jiān)控。 5.2 操作系統(tǒng)監(jiān)控 操作系統(tǒng)層面的性能監(jiān)控主要是對內(nèi)存、CPU、I/O和交換區(qū)的使用情況進行監(jiān)控分析。windows平臺可以通過任務(wù)管理器和perfmon工具查看。如果是unix系統(tǒng)可以使用stat系列命令(vmstat, mpstat, iostat)監(jiān)控內(nèi)存、CPU和I/O的即時變化,使用swap命令查看交換區(qū)的使用情況。如果操作系統(tǒng)安裝了top、topas、glance等使用工具,則使用top、topas、glance將能更為方便地看到WebLogic進程對操作系統(tǒng)的內(nèi)存,CPU和I/O資源使用的即時變化情況。 而網(wǎng)絡(luò)方面的性能可以通過ping和netstat等命令來監(jiān)控,主要幾個關(guān)鍵的網(wǎng)絡(luò)統(tǒng)計值,如數(shù)據(jù)包再發(fā)送、重復(fù)數(shù)據(jù)包和數(shù)據(jù)包偵聽丟失。 說明:本文提到的unix命令并非適用所有操作系統(tǒng),僅供參考。 5.3 數(shù)據(jù)庫監(jiān)控 數(shù)據(jù)庫層面的監(jiān)控這里為oracle9i為例來說明,可以采用oracle自帶的工具Oracle? Interprise Manager Console來監(jiān)控session和sql的執(zhí)行情況。還有其他專業(yè)的數(shù)據(jù)庫監(jiān)控工具可以使用,比如QUEST的spotlight(http://www.quest.com/spotlight-portal/)可以非常形象和直觀地對Oracle數(shù)據(jù)庫的CPU、內(nèi)存、I/O、Data Buffer Size、Shared Pool Size、Redo Buffer等參數(shù)進行即時監(jiān)控,并自動對不正常的參數(shù)以紅色顯示。 5.4 WebLogic監(jiān)控 5.4.1 JVM監(jiān)控 采用java參數(shù)-verbose:gc 來分析JVM的GC非常繁瑣,而且不直觀。使用-Xloggc:gc.log 參數(shù)將GC日志寫入文件,采用GC 工具HPjtune (http://www.javaperformancetuning.com/tools/hpjtune/index.shtml)進行分析,可以輕松看出當前jvm參數(shù)配置是否合理。 嚴格意義上來說HPjtune是一個分析工具,不是監(jiān)控工具。這里不得不提及jRocket,Intel平臺上最快的JVM, 在WebLogic啟動命令中增加-Xmanagement參數(shù),就可以執(zhí)行beajrockit81sp3_142_04 in下console命令監(jiān)控WebLogic的內(nèi)存使用和CPU負載情況。設(shè)置Tools/Preferences菜單中的Mode of operation屬性為developer, jRocket將提供Method Profiler工具,她能夠?qū)⑺性贘Rockit Java虛擬機上執(zhí)行的成員方法的調(diào)用次數(shù)、執(zhí)行的總時間和每次調(diào)用的執(zhí)行時間都統(tǒng)計出來,進行代碼級調(diào)優(yōu),這是jRockit的又一大優(yōu)勢。 5.4.2 Console監(jiān)控 WebLogic Console除了管理配置功能之外,提供了豐富的監(jiān)控功能。通過WebLogic Console,首先我們可以查看服務(wù)器的運行情況。 5.4.2.1 Server監(jiān)控 通過使用服務(wù)器的Performance Monitoring選項卡,可以查看到請求吞吐量,執(zhí)行隊列積壓情況以及JVM棧利用情況。而通過點擊Performance Genaral選項卡中” Monitor all Active Queues...”可以查看所以執(zhí)行線程的當前統(tǒng)計數(shù)據(jù)。此外Monitoring選項卡還可以監(jiān)控JTA和JMS等Service的情況。 5.4.2.2 JDBC監(jiān)控 在連接池Monitoring選項卡中,WebLogic Console為每一個數(shù)據(jù)庫連接池提供了實時統(tǒng)計信息。其中有三個重要參數(shù)可以反應(yīng)WebLogic Server的健康狀況:Connections High、Wait Second High和Waiters High。Connection High表示從服務(wù)器啟動開始后到達池的最大連接數(shù)量,如果大于池的最大數(shù)量,則需要調(diào)整Maxium Capacity。Waiters High表示在沒有可用連接的情況下,應(yīng)用程序等待連接的最大個數(shù)。我們可以根據(jù)Waiters High的大小調(diào)整連接池容量。更多的參數(shù)可以通過Customize this view鏈接添加,參數(shù)含義參考:http://e-docs.bea.com/wls/docs81/ConsoleHelp/domain_jdbcconnectionpool_monitor.html#1104829。 5.4.2.3 WEB監(jiān)控 Web Application Monitoring選項卡可以監(jiān)控WEB應(yīng)用的Session個數(shù),以及Servlet的響應(yīng)情況,激活Session Monitoring Enabled可以獲取所有session的統(tǒng)計情況。更多信息請參考: http://e-docs.bea.com/wls/docs81/ConsoleHelp/web_applications.html#1106723。 5.4.2.4 JMS監(jiān)控 Welogic Console JMS監(jiān)控功能比較多,不僅在Server JMS Monitoring選項卡可以監(jiān)控Active JMS Connections, Pooled JMS Connections和Active JMS Servers的連接和使用情況。還可以監(jiān)控JMS Session Pool、Active JMS Destinations和Durable Subscribers的消費和生產(chǎn)情況。比如,我們可以監(jiān)控到JMS Queue的接收和消費消息的數(shù)量和字節(jié)數(shù)。有關(guān)JMS監(jiān)控的詳細情況可參見:http://edocs.bea.com/wls/docs81/ConsoleHelp/jms_monitor.html。 5.4.2.5 EJB監(jiān)控 EJB監(jiān)控包括對SLSB,SFSB,Entity Bean,MDB四種EJB的監(jiān)控。本人認為EJB監(jiān)控提供了非常豐富的運行時統(tǒng)計信息(http://e-docs.bea.com/wls/docs81/ConsoleHelp/ejb.html#1105036),非常有利于我們對EJB進行性能調(diào)優(yōu)。 SLSB選項卡為用戶提供實例池的運行時統(tǒng)計信息。Pool Miss Ratio 表示實例池的Miss率,Pool Waiter Total Count 表示線程等待bean 實例的累計時間,Pool Timeout Total Count表示超時的線程數(shù)。當Pool Miss Ratio較大時,可以增加max-beans-free-pool。 SFSB可以關(guān)注Cache Miss Ratio和Activation Count。Cache Miss Ratio過大時,調(diào)大max-bean-in-cache未必有幫助,需要嘗試不用的max-bean-in-cache以獲得最低的Cache Miss Ratio。激活將嚴重減慢應(yīng)用程序的速度,如果某一個bean的Activation Count的值過高,那么需要考慮增加max-bean-in-cache的大小。 Entity Bean結(jié)合了SLSB的free pool和SFSB的cache。可以結(jié)合上面的策略進行監(jiān)控。 而MDB僅比SLSB多一個參數(shù)JMSConnection Alive,報告EJB是否成功連接到JMS目的地。 更多Console監(jiān)控信息可參見http://edocs.bea.com/wls/docs81/ConsoleHelp/index.html。 5.4.3 實用工具分析 WebLogic除了提供Console進行應(yīng)用監(jiān)控之外,用戶還可以編寫JMX程序或者通過SNMP協(xié)議進行監(jiān)控。而QUEST Spotlight for WebLogic Server提供了類似WebLogic Console類似的監(jiān)控功能,并對異常情況顯紅。 這里不得不提到實戰(zhàn)中經(jīng)常用來分析性能瓶頸的工具THREAD DUMP,統(tǒng)一的命令是使用 weblogic.Admin 命令 THREAD_DUMP。而在 windows上還可以使用<Ctrl>+<Break> 來創(chuàng)建診斷問題所需的線程轉(zhuǎn)儲Thread Dump,而在unix上使用kill -3 <wlspid>命令。我們從中可以看到WebLogic后臺線程的運行情況,通常需要每隔10秒左右持續(xù)執(zhí)行幾次以助診斷問題。更多信息可以參考BEA實戰(zhàn)集錦。 5.5 應(yīng)用程序分析 應(yīng)用程序分析除了憑借程序員豐富的經(jīng)驗和敏銳的洞察力去人工檢查代碼之外,使用廠家的工具也是節(jié)省時間的不錯選擇。目前市場上有Borland Optimizeit Enterprise Suite和QUEST Jprobe兩個產(chǎn)品可以用來分析性能瓶頸,垃圾收集,內(nèi)存泄漏,線程死鎖和代碼復(fù)蓋等。Hpjmeter是一個免費的工具,也具有以上類似的性能分析功能。 而Borland Optimizeit Server Trace,HP OpenView Transaction Analyzer和Mercury LoadRunner J2EE breakdown都可以用來分解J2EE應(yīng)用從客戶端訪問到最終數(shù)據(jù)庫操作每一層次花費的時間,甚至精確到每一個方法的執(zhí)行時間。Server Trace還具有檢查內(nèi)存泄漏,連接泄漏和錯誤警告等功能,一般在測試環(huán)境中使用。而HP OTVA的優(yōu)勢在于運行時監(jiān)控,LoadRunner優(yōu)勢在于壓力測試。 總結(jié) J2EE調(diào)優(yōu)是一門實踐和經(jīng)驗科學,是一個復(fù)雜而往復(fù)的過程。其原則是:合理。合理,看似簡單,細細品味,意味深長。本文所述的調(diào)優(yōu)策略并不是一成不變的,只是為了給大家一個參考建議,讓大家少走彎路,關(guān)鍵是根據(jù)實際環(huán)境調(diào)優(yōu)。歡迎有興趣的朋友在論壇上積極討論和批評指正。 參考文獻 [1]BEA WebLogic Server edocs: http://e-docs.bea.com/wls/docs81/perform/index.html [2]Gregory Nyberg & Robert Patrick :Mastering BEA WebLogic Server [3]Jack Shirasi:Java Performance Tuning |