原文來自,[url]http://wiki.jboss.org/wiki/JBossASTuningSliming[/url],翻譯的不當之處請諒解。
JBossAS的調優
|
基於JBoss 3.2.6 。
前言
這個建議主要是如果對JBossAS進行調優和瘦身的. 這個概念在多數情況是交叉的。當通過瘦身減少閒置服務線程並不能帶來大的性能影響的時候,允許你使用較少的內存和資源對其他性能方便進行調整。當然它可以縮短啓動時間。而且,作爲一般的安全觀念――移除你不使用的服務。我們將分開兩個種類: 瘦身和調優. 首先我們使用默認的配置並從那裏開始瘦身(對於clustering的話題,將在以後的wiki頁面進行討論 ;-) ). 這個建議不牽扯開發者和管理角色交叉調優的區域開發者和管理角色 (應用程序調優象cache大小一樣). 這主要是對於管理調優的建議.
這建議將做技術上非J2EE平臺兼容(3.2.6無論如何不順從)的JBoss實例的有關的那些注意,象除去J2EE關鍵 服務的那樣將導致JBoss 失敗TCK。多數性能調優/管理任務工作,在現實世界結構裏,在技術上屬於這個類別。
假設你已經複製server/default 文件夾並將它重新命名爲server/slim.
調優
Java Virtual Machine Java虛擬機
l 使用64位的機器和64位的VM,以便你能使用大的heap(堆)大小,通常比2-4GB的大。64位支持在所有最新的SPARC/Solaris 寄存器運行Solaris 9 或者以後的版本是有效的, Itanium 使用 JDK 1.4, 或者在Linux x64 上使用JDK 5.
l 如果你不使用上面的最大32位heap空間(2-4 GB 的heap),不要使用 –d64. 使用64位地址需要更多的內存來做同樣的工作量,並且對於應用程序不需要如此多的內存來說並不能提供更大優勢。
l 除了避免額外小的heaps外還要避免額外大的heaps. (我們不能告訴你具備什麼資格,因爲它取決於你正做什麼). 這影響generational 垃圾收集和掃描heap的總的時間. 有效的調整一個小heap是困難的 (即使你的應用程序僅僅需要使用200MB,如果你使用並行垃圾收集+CMS,然後你將需要遠高於512MB). 特大號的heaps爲垃圾收集花費不必要的時間掃描內存。
l 避開 Sun 1.4 VM. JDK 5 主要是在垃圾收集方面非常的好.
l 使用 -server 參數除了使用其他-XX:ThreadStackSize=128k (Solaris) 或者 -Xss128k (其他任何平臺). 在Solaris 上 -Xss128k 什麼也沒有做 (你只可以設置較大的線程棧大小). 這允許你每個線程通過使用較少的內存達到創建更多線程的目的。but might result in blown stacks with extremely recursive code. 然而, 128k 棧 is still nothing to shake a stick at.
l 你確實將使用一個超過2個處理器的多核心機器,及使用不同的平行和並行垃圾收集選擇 (我們談及這先進的JBoss訓練暗示伏筆) 對於最大性能和高拉機回收吞吐量. 不過,你確實需要理解怎麼調整才能使得垃圾收集很好的工作。JDK 5大部分是自我調整.
l JDK 1.4的默認 NewSize? 不是好的猜想. 壞的經驗法則: < 20% 是一個好的 NewSize?. 20%以上的消費是危險的,這是JDK令人討厭的一個,能導致它psychotically運行所有滿垃圾回收和從未 unsuspend 或者釋放出 足夠多的內存. JDK 5 似乎沒有展示出這個bug,並且似乎已回升更理智的默認值。
JBoss/Java on Linux
如果你正在運行JBoss AS在Linux服務器上,你應該看看這篇文章的作者: Andrew Oliver, Jboss事業部, Red Hat公司, 顧問 ,在 在Linux服務器上怎麼優化Jboss/Java
Tomcat
l 編輯你的server/slim/jbossweb-tomcat5?.sar/server.xml 文件
l 檢查你正在使用的連接器的XML文檔. 例如, HTTP 連接器:
<Connector port="8080" address="${jboss.bind.address}"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true"/>
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true"/>
l 你應該有多於你最大預期25%(經驗法則)的線程(maxThreads)來處理負載(將來一次性的併發訪問)
l 你應該有minSpareThreads 等於恰好比你正常負載多一點
l 你應該有maxSpareThreads等於恰好比你峯值負載多一點
l minSpareThreads 意思是 "啓動準備就緒, 總是保持至少這些線程來等待處理"
l maxSpareThreads means "如果我們總是超過minSpareThreads那麼總是保持 maxSpareThreads 來等待處理"
l 移除任何不需要的值和日誌。如果你不用JBoss的安全,移除這個安全值 (見下面).
l Precompile(預編譯) JSPs. (這個內置的編譯器非常的會,它可能對於小型站點不值得做.)
l 在你的sever/slim/jbossweb-tomcat50.sar/conf/web.xml 裏關閉開發("development")模式
RMI的遠程調用
默認情況下, JBoss爲進來的每個RMI請求創建一個新線程. 在一個大系統中這一般不是高效率的. 其次,它允許無限制的連接在性能或者通信峯值或者run-away 連接方面創建客戶端可能是危險的。爲了補救這個你應該考慮轉向被集中的池請求.
編輯 server/slim/conf/standardjboss.xml
通過改變每個XML分段讀數把所有代理綁定改變成被集中的池請求:
<invoker-mbean>jboss:service=invoker,type=jrmp</invoker-mbean>
到
<invoker-mbean>jboss:service=invoker,type=pooled</invoker-mbean>
Log4j
l 默認情況下, JBoss的日誌被打印到控制檯和server.log文件裏並且它默認使用的日誌級別是 "INFO".
l 考慮不記錄到System.out (你也能仍舊想改變方向以抓取JVM 錯誤)
l 考慮改變日誌的級別爲ERROR. 觀察JBoss的log4j配置文件的變化,你可以在其運行的時候改變這個配置。
l 給你的java class層次增加一個類別過濾器.
關掉打印到控制檯的日誌(console logging):
l 編輯 server/slim/conf/log4j.xml
l 改變下面的XML 片段:
<root>
<appender-ref ref=CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
<appender-ref ref=CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
修改成
<root>
<appender-ref ref="FILE"/>
</root>
<appender-ref ref="FILE"/>
</root>
l 然後你可以刪除此片段:
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="Target" value="System.out"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
</layout>
</appender>
<errorHandler class="org.jboss.logging.util.OnlyOnceErrorHandler"/>
<param name="Target" value="System.out"/>
<param name="Threshold" value="INFO"/>
<layout class="org.apache.log4j.PatternLayout">
<!-- The default pattern: Date Priority [Category] Message\n -->
<param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
</layout>
</appender>
改變日誌的級別:
l 編輯 server/slim/conf/log4j.xml
l 移除/註釋 這些XML 片段:
<category name="org.apache">
<priority value="INFO"/>
</category>
<!—極限 org.jgroups 類別爲INFO -->
<category name="org.jgroups">
<priority value="INFO"/>
</category>
<priority value="INFO"/>
</category>
<!—極限 org.jgroups 類別爲INFO -->
<category name="org.jgroups">
<priority value="INFO"/>
</category>
l 改變這個XML片段以改變root類別:
<root>
<appender-ref ref="CONSOLE"/> <!—你可能在前面已經移除這個-->
<appender-ref ref="FILE"/>
</root>
<appender-ref ref="CONSOLE"/> <!—你可能在前面已經移除這個-->
<appender-ref ref="FILE"/>
</root>
看上去像這樣
<root>
<priority value="ERROR" />
<appender-ref ref="CONSOLE"/> <!--你可能在前面已經移除這個-->
<appender-ref ref="FILE"/>
</root>
<priority value="ERROR" />
<appender-ref ref="CONSOLE"/> <!--你可能在前面已經移除這個-->
<appender-ref ref="FILE"/>
</root>
另外,如果你使用了hibernate的話:
l 編輯 server/slim/conf/log4j.xml
l 增加如下XML 片段
<category name="org.hibernate" >
<priority value="INFO" />
</category>
<priority value="INFO" />
</category>
最後, 在log4j中也許是最重要的事情,在你擁有的 class 結構上確保你的極限的日誌級別. 假設你正在使用的log4j打算不向System.out打印任何東西. 這將大大的降低log4j的額外開銷,並且允許你完全享受益處,像如果調用(log.isDebugEnabled())....如果你那麼做,那麼你的代碼中的所有日誌都將通過appender進行格式化, 這個threshold 在appender將被從日誌消息中去除出去. 它能產生大量的垃圾信息。假設你的java package 以“a.b”開始的話, 在log4j.xml增加一些像這樣的信息:
<!--極限a.b 類別爲INFO -->
<category name="a.b">
<priority value="INFO"/>
</category>
<category name="a.b">
<priority value="INFO"/>
</category>
這個可以增加到你在org.apache 和 org.jboss (見上文)中找到過濾類別的同一區域.
部署掃描器(Deployment Scanner )
l 部署掃描器每隔5秒掃描一次,在比較慢的文件系統上尤其吃週期 (*cough* NTFS *cough*).
l 見下面的瘦身stuff on ,怎麼調整秒數以至於它發生的不那麼頻繁或者不全部發生。
無狀態會話Beans(Stateless Session Beans )
l EJB 1.x-2.x 無狀態會話beans operate with an ill-advised pooling model (required by the specification). 如果你find你需要考慮設置比默認(10)實例要多的最小線程池的大小:
編輯 server/slim/conf/standardjboss.xml, 向下滾動:
<container-configuration>
<container-name>Standard Stateless SessionBean</container-name>
<call-logging>false</call-logging>
<invoker-proxy-binding-name>stateless-rmi-invoker</invoker-proxy-binding-name>
<container-interceptors>
<container-name>Standard Stateless SessionBean</container-name>
<call-logging>false</call-logging>
<invoker-proxy-binding-name>stateless-rmi-invoker</invoker-proxy-binding-name>
<container-interceptors>
並找到:
<container-pool-conf>
<MaximumSize>100</MaximumSize>
</container-pool-conf>
</container-configuration>
<MaximumSize>100</MaximumSize>
</container-pool-conf>
</container-configuration>
改變它爲:
<container-pool-conf>
<MinimumSize>100</MinimumSize>
<MaximumSize>100</MaximumSize>
<strictMaximumSize/>
<strictTimeout>30000</strictTimeout>
</container-pool-conf>
</container-configuration>
<MinimumSize>100</MinimumSize>
<MaximumSize>100</MaximumSize>
<strictMaximumSize/>
<strictTimeout>30000</strictTimeout>
</container-pool-conf>
</container-configuration>
在很大程度上一種服務器環境中不希望這些池增長和縮減(因爲它導致內存碎片,不如潛在的堆使用). 從性能上來說, nuber要足夠的大以提供保證你的所有請求不阻塞的服務。
CMP 調整
連接池(Connection Pools)
l 不要使用XA版本,除非你真的知道你需要使用它. XA連接的性能不好.
l
與其在可用的地方利用數據庫特定的"ping"支持"check-connection"(檢查連接),或者利用數據庫特定驅動的fail-over支持倒不如從不checking connections. (記住並非所有的優化選項都適合你的環境,我們正在討論的是最佳情況) 。