簡介
IBM WebSphere Application Server 是一種可靠的企業級應用服務器,它提供了一組核心組件、資源和服務,供開發人員在應用程序中使用。每個應用程序都具備特有的需求,並且經常采用截然不同的方式使用應用服務器的資源。為了提供高度靈活性並支持這種廣泛的應用程序,WebSphere Application Server 提供了一組全面的參數來幫助您增強對應用程序的調優。
應用服務器已經為最常用的調優參數設置了默認值,以確保能為最廣泛的應用程序提供開箱即用的性能改善。但是,由於任意兩個應用程序都不可能采用完全相同的方式來使用應用服務器,因此無法確保一組調優參數能適用於所有應用程序。這也突顯了對應用程序執行有重點的性能測試和調優的重要性。
本文將討論在 WebSphere Application Server V7.0(和之前發行版)中最常使用的一些參數,以及對它們進行調優的方法。與其他相關文章提供的調優建議不同,本文將使用 Apache DayTrader Performance Benchmark Sample 案例研究作為本文的上下文。借助 DayTrader 應用程序,您可以清楚地確定所使用的主要服務器組件,對這些區域進行重點調優,並觀察各種調優更改所帶來的收益。
在繼續閱讀之前,需要記住關於應用服務器性能調優的一些事項:
提高性能經常會犧牲應用程序或應用服務器的一些特性或功能。在計算性能調優更改時應該仔細考慮性能和特性之間的權衡。
應用服務器之外的一些因素有時會影響性能,包括硬件和操作系統配置、系統中運行的進程、後端數據庫資源的性能、網絡延遲等等。您在自己執行性能評估時,必須將這些因素考慮在內。
此處討論的性能改善僅針對 DayTrader 應用程序,並且特定於此處描述的工作負載組成及所支持的硬件和軟件棧。您通過本文介紹的調優更改實現的應用程序性能提升肯定會有所不同,並且應該通過您自己的性能測試進行評估。
DayTrader 應用程序
Apache DayTrader Performance Benchmark Sample 應用程序模擬了一個簡單的股票交易系統,它允許用戶登錄/注銷、查看股票組合、查詢股票報價、交易股票以及管理帳戶信息。DayTrader 不僅是一個優秀的功能測試應用程序,還提供了一組標准的工作負載,用於描述和測量應用服務器和組件級性能。DayTrader(以及它所依托的由 IBM 開發的 Trade Performance Benchmark Sample 應用程序)的初衷並非提供最佳性能,而是對應用服務器發行版和備選實現樣式、模式進行比較。
DayTrader 基於一組核心 Java™ Enterprise Edition (Java EE) 技術,包括用於表示層的 Java servlets 和 JavaServer™ Pages (JSPs)、Java 數據庫連接 (JDBC)、Java Message Service (JMS)、Enterprise JavaBeans™ (EJBs) 以及用於後端業務邏輯和持久層的消息驅動 beans (MDBs)。圖 1 提供了應用程序體系結構的高級視圖。
圖 1. DayTrader 應用程序視圖
為了便於您評估一些常見的 Java EE 持久性和事務管理模式,DayTrader 提供了三種不同的業務服務實現。這些實現(或運行時模式)如表 1 所示。
表 1. DayTrader 實現 運行時模式 模式 描述 Direct Servlet 到 JDBC 使用自定義 JDBC 代碼直接對數據庫執行創建、讀取、更新和刪除 (CRUD) 操作。數據庫連接、提交和回滾將在代碼中手動管理。 Session Direct 從 Servlet 到 Stateless SessionBean 到 JDBC 使用自定義 JDBC 代碼直接對數據庫執行 CRUD 操作。數據庫連接將在代碼中手動管理。數據庫提交和回滾將由無狀態會話 bean 自動管理。 EJB 從 Servlet 到 StatelessSessionBean 到 EntityBean EJB 容器承擔所有查詢、事務和數據庫連接的責任。
本文將討論這些運行時模式,以便演示各種調優更改對這三種常見 Java EE 持久性和事務實現風格的影響。
導航 WebSphere Application Server 可調參數
如前所述,在執行性能調優時,理解應用程序體系結構、服務器組件以及所使用的資源是非常重要的。具備這些知識之後,您可以迅速過濾可調參數並專注於直接影響應用程序的核心可調參數。
性能調優通常從 Java Virtual Machine (JVM) 開始,它是應用服務器的基礎。依照之前的觀點,調優主要是由應用程序所使用的應用服務器組件所驅動。舉例來說,您可以使用體系結構圖(圖 1)來確定 DayTrader 應用程序的一些主要可調服務器組件:
Web 和 EJB 容器
相關線程池
數據庫連接池
默認消息傳遞提供者
本文其余部分將根據上面列出的組件來詳細討論一些會對 DayTrader 性能造成影響的調優選項。這些選項可以分為以下類別:
基本調優:包括一些最常調節和使用的應用服務器組件,從 JVM 開始。這些設置通常占據最大份量。
高級調優:第二種高級調優參數通常與特定的場景相關,且常用於發掘系統的最大性能。
異步消息傳遞調優:此處討論的選項特定於使用 WebSphere Application Server 的消息傳遞組件實現異步消息傳遞的應用程序。
我們將詳細討論這類調優參數的適用性,它們的功能權衡以及最終對性能造成的影響(如果可能,針對各種持久性和事務管理模式)。我們還將介紹可以在調優過程中為特定參數提供協助的一些工具。
基本調優
本節將討論:
JVM 堆大小
線程工具大小
連接池大小
數據源狀態緩存大小
通過引用傳遞的 ORB
a. JVM 堆大小
JVM 堆大小參數將直接影響垃圾收集行為。通過增加 JVM 堆大小,可以在出現分配故障並觸發垃圾收集之前創建更多對象。這通常可以讓應用程序增加各垃圾收集 (GC) 周期之間的間隔時間。遺憾的是,增加堆大小的一個缺點是查找和處理需要垃圾收集的對象所需的時間也會隨之增加。因此,JVM 堆大小調優經常涉及確定垃圾收集之間的間隔時間與執行垃圾收集所需的暫停時間之間的平衡點。
要對 JVM 堆大小進行調優,需要啟用詳細模式的(verbose)GC。此操作可以在 WebSphere Application Server 管理控制台中完成:依次選擇 Servers => Application servers => server_name => Process definition => Java Virtual Machine。通過啟用詳細模式的 GC,JVM 在每次垃圾收集時都會打印輸出有用的信息,比如堆中的空閒和已使用字節、垃圾收集之間的間隔以及暫停時間。這些信息將記錄在 native_stderr.log 文件中。隨後,各種工具可以使用該文件來可視化堆使用情況。
WebSphere Application Server 的默認堆設置如下:初始堆大小為 50 MB,最大堆大小為 256 MB。通常情況下,應該將最小和最大堆大小設置為相同值,以防止 JVM 動態調整堆設置。通過將重要參數固定為常量,這不僅有助於簡化 GC 分析,還可以避免與分配和取消分配更多內存相關的成本開銷。將最大和最小堆大小設置為相同值的缺點在於,初次啟動 JVM 時會比較慢,因為 JVM 必須分配更大的堆。
在一些場景中,將最大和最小堆大小設置為不同值是更有利的。其中一個場景就是運行不同工作負載的多個應用服務器實例托管在同一服務器上。在此場景中,JVM 可以動態響應不斷變化的工作負載需求,並更加高效地使用系統內存。
測試
在啟動詳細模式 GC 的情況下,我們針對初始和最大堆大小分別設置為 256 MB、512 MB、1024 MB 和 2048 MB 執行了 4 次測試。您可以手動分析詳細模式 GC,但可以通過一些圖形工具,比如 IBM Monitoring and Diagnostic Tools for Java - Garbage Collection and Memory Visualizer 工具,可以顯著簡化此過程。該工具用於在實驗測試中查看詳細模式 GC 數據,以便在查找 DayTrader 應用程序的適當堆大小時可以做出一些調整。
在詳細模式垃圾收集輸出中監視的第一批項目包括收集後的空閒堆。該指標常用於確定應用程序中是否出現的任何 Java 內存洩漏。如果此指標未達到穩定狀態值,並隨時間持續減小,則明確表示應用程序中出現了內存洩漏。收集後的空閒堆指標還可以與堆大小結合,共同計算服務器和應用程序所使用的內存工作集(或 “內存占用”)。只需要從總堆大小中減去空閒堆值就可以得到這個值。
圖 2. 收集後的空閒堆匯總
需要注意,雖然詳細模式 GC 數據和圖 2 中的表可以幫助檢測 Java 堆中的內存洩漏,但無法檢測本機內存洩漏。發生本機內存洩漏的情況是本機組件(比如使用 C/C++ 編寫並通過 Java Native Interface API 調用的供應商本機庫)造成本機內存洩漏到 Java 堆外部。在這種情況下,需要使用平台相關工具(如 Linux® 平台上的 ps 和 top 命令、Windows® 平台上的 Perfmon 命令等)來監控 Java 進程的本機內存使用。WebSphere Application Server Support 分頁 提供了關於診斷內存洩漏的詳細文檔。
另外還需要考慮各收集任務的垃圾收集間隔時間和平均暫停時間。GC 間隔時間是垃圾收集周期之間的間隔時間。暫停時間是垃圾收集周期完成所需的時間。圖 3 展示了四種堆大小的垃圾收集間隔時間。它們最終的平均值是 0.6 秒 (256 MB)、1.5 秒 (512 MB)、3.2 秒 (1024 MB) 和 6.7 秒 (2048 MB)。
圖 3. 垃圾收集間隔時間
圖 4 顯示了四種堆大小的平均暫停時間。在實驗測試中,它們最終的平均值分別是 62 ms (256 MB)、69 ms (512 MB)、83 ms (1024 MB) 和 117 ms (2048 MB)。這明確展示了增加 Java 堆大小的標准權衡。當堆大小增加時,GC 之間的間隔將增加,這樣便可以在 JVM 暫停以執行垃圾收集例程之前完成更多任務。但是,增加堆大小還意味著垃圾收集器必須處理更多對象,從而能增加 GC 暫停時間。
圖 4. 平均暫停時間
GC 間隔和暫停時間共同構成了垃圾收集所耗費的時間。垃圾收集所花費的時間百分比將顯示在 IBM Monitoring and Diagnostic Tools for Java - Garbage Collection and Memory Visualizer 工具中,並且可以使用以下公開計算得出:
各種情況下垃圾收集所占用的時間以及形成的吞吐量(每秒請求數)如圖 5 所示。
圖 5. 垃圾收集所戰用的時間和吞吐量
建議將 DayTrader 應用程序的初始和最大堆大小設置為 1024 MB。至此,您的邊際收益將開始逐漸遞減,因為進一步增加堆大小將不會帶來成比例的性能改進。這在較長垃圾收集間隔時間與較短暫停時間之間達到了平衡,從而減少了垃圾收集所花費的時間。
JVM 調優的另一個重要方面是垃圾收集策略。三種主要的 GC 策略如下:
optthruput:(默認)當應用程序暫停時,在垃圾收集過程中執行標記和清掃操作,以便最大限度提高應用程序吞吐量。
optavgpause:在應用程序運行時並發執行標記和清掃操作,以便最大限度縮短暫停時間;這將提供最理想的應用程序響應時間。
gencon:區別對待短期和長期對象,同時提供較短的暫停時間和較高的應用程序吞吐量。
DayTrader 應用程序並未使用許多長期對象,並且在使用默認的 GC 策略時性能最佳。但是,應用程序是各不相同時,因此您應該評估各 GC 策略,以便找到最適合您應用程序的策略。developerWorks 文章 垃圾收集策略 提供了關於 GC 策略的更多信息。
圖 6 展示了通過在各種不同的 DayTrader 運行時模式下調優 JVM 堆大小所實現的性能提升。在該表中,藍柱用於表示基准吞吐量值,而紅柱表示調整所討論的調優參數後的吞吐量值。為了便於各種運行時模式之間的相對吞吐量差異,所有度量都將與 EJB 模式基准進行比較。
舉例來說,在調優之前,Session Direct 和 Direct 模式分別比 EJB 模式基准快 23% 和 86%。第二根軸上的線表示 各運行時模式下的總體性能改善。在本例中,JVM 調優為三種運行時模式帶來了不同程度的改善,因為它們分別采用所特有的對象分配模式。性能改善的范圍從 3%(JDBC 模式)到 9%(EJB 模式)不等。
這方面的信息將在結束對各調優參數的討論時給出。根據上一節所提供的參數,調節各調優參數後實現的應用程序性能改善是可以累加的。本文結尾部分提供的表(圖 22)列出了可用的所有調優更改帶來的總體性能改善。
圖 6. 調優 JVM 堆大小帶來的性能改進
b. 線程池大小
服務器執行的各項任務運行於 WebSphere Application Server 的許多線程池中的某個線程之上。線程池允許服務器的組件重用線程,從而避免了在運行時創建新線程來服務各個新請求。應用服務器中最常用(和調優)的三個線程池如下:
Web 容器:當請求通過 HTTP 傳入時使用。在 DayTrader 體系結構圖(圖 1)中,可以看到大多數流量都通過 Web Container 流入了 DayTrader。
默認:當針對消息驅動 bean 的請求傳入時,或者沒有為特定傳輸鏈定義具體線程池時使用。
ORB:當針對企業 bean 的請求從 EJB 應用程序客戶機、遠程 EJB 接口或另一台應用服務器通過 RMI/IIOP 傳入時使用。
與線程池相關的重要調優選項如表 2 所示。
表 2. 可調優的線程池選項 設置 描述 最小大小 池中准許的最大線程數量。當應用服務器啟動時,最初不會向線程池分配任何線程。線程將作為分配給需要它們的應用程序服務器的工作負載被添加到線程池中,直到池中的線程數量等於在最小大小字段中指定的數值。此後隨著工作負載的變化還會添加和刪除一些線程。但是,池中的線程數量從來都不會低於在最小大小字段中指定的數值,即便其中一些線程是空閒的。 最大大小 指定默認線程池中的最大線程數量。 線程靜止超時 指定回收線程之前應該間隔的靜止時間(毫秒)。值為 0 表示無需等待,負值(小於 0)則表示永遠等待。
假定機器包含一個應用服務器實例,則一個良好的實踐是每個服務器 CPU 核心為默認線程池使用 5 個線程,每個服務器 CPU 為 ORB 和 Web 容器線程池使用 10 個線程。對於 CPU 多於 4 個的機器,默認設置通常可以滿足大多數應用程序的需求。如果機器有多個應用服務器實例,則這些相應地減小這些值的大小。相反,有時也需要增加線程池大小來解決應對 I/O 較慢或後端連接需要長時間運行的問題。表 3 列出了最常調優的線程池的默認線程池大小和靜止超時。
表 3. 默認線程池大小和靜止超時 線程池 最小大小 最大大小 靜止超時 默認 20 20 5000 ms ORB 10 50 3500 ms Web 容器 50 50 60000 ms
要修改線程池設置,可以在管理控制台中導航到 Servers => Application Servers => server_name => Thread Pool。您還可以使用 Performance Advisors 來獲得關於線程池大小和其他設置的建議。
IBM Tivoli® Performance Viewer 是嵌入在管理控制台中的一款工具,它允許您查看幾乎任何服務器組件的性能監控基礎設施(Performance Monitoring Infrastructure,PMI)數據。查看器將提供建議幫助用戶調優系統,並針對效率低下的設置提供一些可行的備選建議。訪問 WebSphere Application Server Information Center,了解如何使用 Tivoli Performance Viewer 來啟動和查看 PMI 數據。
圖 7 展示了當 DayTrader 應用程序啟動並在穩定、峰值負載下運行時 Web container 線程池的 PMI 數據。池大小(黃色)是池中線程數量的平均值,而活動計數(紅色)是當前活動線程的數量。從這個圖中可以看出,默認設置,即最多 50 個 Web 容器線程,最適合這種情況,因為所有 50 個線程都未被分配,並且並發工作負載平均使用大約 18 個線程。由於默認線程池大小已經足夠,因此不需要對線程池大小進行修改。
圖 7. Web 容器線程池的 PMI 數據
在 WebSphere Application Server V6.x 之前,並發客戶機連接與 Web 容器線程池中的線程之間存在一一對應的關系。換句話說,如果有 40 個客戶機在訪問應用程序,則有 40 個線程需要服務請求。在 WebSphere Application Server V6.0 和 6.1 中,由於引入了 Native IO (NIO) 和 Asynchronous IO (AIO),因此能夠使用相對較少的線程來擴展數千客戶連接。這解釋了為何在圖 7 中平均只使用 18 個線程來服務來自 HTTP 負載驅動程序的 50 個並發客戶機連接。根據此信息,可以減小線程池大小,以便降低管理大小超過需要的線程池的開源。但是,這會影響服務器響應負載峰值(這時需要大量線程)的能力。應該通過仔細考慮來確定線程池的大小,包括預期的平均和峰值工作負載。
c. 連接池大小
每次當應用程序嘗試訪問後端庫時(比如數據庫),它都需要資源來創建、維持和釋放到該數據庫的連接。為了緩解此過程對總體應用程序資源的壓力,應用服務器允許您建立一個後端連接池,用於在應用服務器上共享應用程序。連接池將連接開銷分散分布在若干用戶請求中,以便保留應用程序資源供未來請求使用。與連接池相關的重要調優選項如表 4 所示。
表 4. 連接池調優選項 設置 描述 最少連接數 要維持的最少物理連接數量。如果連接池的大小小於或等於最小連接池大小,則 未使用的超時線程(unused timeout thread) 將不會放棄物理連接。但是,池並不會單獨創建連接來確保維持了最小連接池大小。 最大連接 可以在這個池中創建的物理連接的最大數量。它們是到後端數據庫的物理連接。達到這個數值時,將不會再創建新的物理連接;請求者必須等待直到當前使用的某物理連接返回到池中,或者直到拋出一個 ConnectionWaitTimeoutException 異常(均基於連接超時設置)。設置較高的最大連接值有時會造成連接請求淹沒您的後端資源。 線程靜止超時 指定在線程回收之前應該等待的靜止時間(毫秒)。值為 0 表示不需要等待,負值(小於 0)則表示永遠等待。
調優連接池的目標是確保各線程都有一個數據庫連接,並且請求不需要排隊以等待訪問數據庫。對於 DayTrader 應用程序來說,每個任務都需要對數據庫執行一次查詢。由於每個線程都需要執行一個任務,因此各並發線程都需要一個數據庫連接。通常,通過 HTTP 傳入的所有請求都將在 Web 容器線程上執行。因此,最大連接池大小至少應該達到 Web 容器線程池的最大大小。但是,有時請求會傳入到默認的線程池中,比如通過消息傳遞 beans 的異步模式。
總的來說,通用的最佳實踐是確定哪些線程池服務任務需要 DataSource 連接並相應調節池的大小。在本例中,最大連接池大小被設置為默認和 Web 容器線程池的最大大小 (70)。要修改連接池設置,可以在管理控制台中導航到 Resources => JDBC => Data Sources => data_source => Connection pool properties。記住,從連接管理的角度來看,所有應用程序都不能具有 DayTrader 那麼優異的表現,因此可以為一個線程使用多個連接。
圖 8 顯示了 DayTrader 在穩定狀態峰值負載下使用默認連接池大小(1 最小/10 最大)運行時連接池的 PMI 數據。FreePoolSize(黃色)是池中空閒連接的數量,而 UseTime(綠色)是連接所使用的平均時間(毫秒)。從此圖中可以看出所有 10 個連接始終都在使用中。除了表格指標之外,該表還顯示其他一些重要指標:WaitingThreadCount 顯示 33 個線程等待數據庫連接的平均 WaitTime 為 8.25 ms,並且 PercentUsed 指標表明池的總體占用率為 100%。
圖 8. 調優連接池之前 PMI 指標
圖 9 顯示了將連接池大小調優為 10(最小)/70(最大)後的同一表。這表明有大量空閒連接可用,且沒有線程在等待連接,從而實現了更快的響應速度。
圖 9. 調優連接池後的 PMI 指標
圖 10. 調優連接池大小後的性能改進
d. 數據源語句緩存大小
數據源語句緩存大小指定每次連接可以緩存的經過准備的 JDBC 語句的數量。WebSphere Application Server 數據源將優化經過准備的語句和可調用的語句,它可以緩存未在活動連接中使用的語句。如果您的應用程序像 DayTrader 那樣使用許多語句,則增加此參數有時可以改善應用程序性能。要配置語句緩存大小,可以導航到 Resources => JDBC => Data sources => data_source => WebSphere Application Server data source properties。
可以使用一些不同的方法來調優數據庫語句緩存大小。其中一個技巧就是審查所有獨特的、經過准備的語句的應用程序代碼(或從數據庫或數據庫驅動程序收集到的 SQL 跟蹤),並確保緩存大小大於該值。其一種方法是迭代式的增加緩存大小並在峰值穩定狀態負載下運行應用程序,直到 PMI 指標不再報告任何緩存丟棄操作。圖 11 展示了連接池的相同 PMI 表,這次數據庫語句緩存大小從默認值 (即 10)增加到了 60。PrepStmtCacheDiscardCount 指標(紅色)表示由於緩存已滿而被丟棄的語句的數量。回過頭來看圖 9 中的表,在調優數據源語句緩存大小之前,被丟棄的語句的數量超過 170 萬條。而圖 11 顯示,調優緩存大小後再也沒有出現丟棄語句的情況。
圖 11. 調優數據源語句緩存大小之後的 PMI 指標
圖 12. 增加數據源語句緩存大小之後的性能改進
e. ORB 通過引用傳遞
Object Request Broker (ORB) 通過引用傳遞選項確定,在處理 EJB 請求中涉及的參數對象時應該使用通過引用傳遞還是通過值傳遞語義。要找到此選項,在管理控制台中導航到 Servers => Application Servers => server_name => Object Request Broker (ORB)。默認情況下,此選項是禁用的,並且將各參數對象的副本傳遞給調用的 EJB 方法。與向已有參數對象傳遞簡單的引用相比,這種方式的開銷要高很多。
總的來說,ORB 通過引用傳遞選項基本上將調用的 EJB 方法作為本地調用對待(甚至對於帶遠程接口的 EJB),並避免必需的對象復制操作。如果遠程接口不是絕對必需的,則一種稍微簡單的、不需要調優的替代方案就是使用帶本地接口的 EJB。但是,使用本地而不是遠程接口,您會損失與遠程接口、分布式環境中的位置透明性以及工作負載管理功能相關的一些收益。
僅當 EJB 客戶機(即 servlet)和所調用的 EJB 模塊位於相同的類加載器中時,ORB 通過引用傳遞選項才能夠帶來收益。這一需求意味著 EJB 客戶機和 EJB 模塊必須部署在相同的 EAR 文件中,並在相同的應用服務器實例中運行。如果 EJB 客戶機和 EJB 模塊被映射到不同的應用服務器實例(通常表示為 split-tier),則必須使用通過值傳遞的語義來遠程調用 EJB 模塊。
由於 DayTrader 應用程序在相同的 EAR 中包含 WEB 和 EJB 模塊,並且兩者都將被部署到相同的應用服務器實例中,因此 ORB 通過引用傳遞選項可用於實現性能提升。從圖 13 中的度量可以看出,此選項讓 DayTrader 從中顯著受益,來自 servlet 的所有請求都將通過遠程接口傳遞給無狀態會話 bean。但直接模式除外,這時 EJB 容器會繞道采用直接 JDBC 和手動事務。
圖 13. ORB 通過引用傳遞的性能改進
高級調優
討論要點:
Servlet 緩存
HTTP 傳輸持久性連接
大分頁支持
禁用未使用的服務
Web 服務器位置
a. Servlet 緩存
WebSphere Application Server 的 DynaCache 為服務器所生成的對象和分頁分段提供了一個通用的內存緩存服務。DistributedMap 和 DistributedObjectCache 接口可以在應用程序中用於緩存和共享 Java 對象,其方法是將引用存儲到緩存中的這些對象中以便隨後使用。另一方面,Servlet 緩存使 servlet 和 JSP 響應分段能由一組可定制的緩存規則來存儲和管理。
在 DayTrader 應用程序中,每次訪問用戶的主頁時都會顯示一個 Market Summary。該摘要信息包含股票漲跌榜的前 5 名和後 5 名,以及當前的股票索引和交易量。此活動需要執行一些數據庫查詢操作,因此會造成加載用戶主頁出現顯著延時。借助 servlet 緩存,marketSummary.jsp 可以保存在緩存中,這可以從基本上避免這些開銷大的數據庫查詢操作,從而改善用戶主頁的響應速度。可以配置緩存對象的刷新間隔,清單 1 中的示例將該值設定為了 60 秒。Dynacache 還可以用於緩存 DayTrader 中的其他 servlet/JSP 分段和數據。本例將演示通過緩存來避免復雜的服務器操作可以實現哪些改善。
要啟用 Servlet 緩存,在管理控制台中導航到 Servers => Application servers => server_name => Web container settings => Web container。必須在 cachespec.xml 文件定義到要緩存的 servlet 或 JSP 的 URI 路徑,該文件位於 Web 模擬的 WEB-INF 目錄中。對於 DayTrader 中的 marketSummary.jsp 來說,cachespec.xml 的內容與清單 1 相似。
清單 1. cachespec.xml
圖 14. servlet 緩存的性能改進
b. HTTP 傳輸持久連接
持久連接指定傳出的 HTTP 響應應該使用持久(保持活動狀態)連接,而不是在請求或響應交換後關閉的連接。在許多情況下,可以通過單一 HTTP 連接許可的持久請求的最大數量來實現性能提升。通過讓每個連接可支持的持久請求不受限制,SSL 連接可以顯著的性能改進,因為 SSL 連接會導致通過交換鍵和協調協議來完成 SSL 握手過程,從而增加開銷。通過最大限度地增加每個連接可處理的請求數量,可以最大限度地減小此開銷的影響。另外,通過保持連接為打開狀態,而不是針對各請求打開或關閉連接,響應速度快的高吞吐量的應用程序也可以實現性能提升。當此屬性設置為 0(零)時,連接將在應用服務器運行過程中一直保持為打開狀態。但是,如果涉及到安全性問題,則應該仔細考慮這項設置,因為當客戶機嘗試建立始終活動的連接時,此參數可以幫助防止拒絕訪問攻擊。
可以在管理控制台中設置 HTTP 傳輸持久連接,方法是導航到 Servers => Application servers => server_name => Ports。然後,單擊與要更改的 HTTP 傳輸渠道設置相關的端口的 View associated transports。
在 DayTrader 測試的過程中,每個連接的最大持久請求數量(Maximum persistent requests per connection)的值從 100(默認)更改為不受限制。圖 15 中的表顯示了通過 HTTP(非 SSL)和 HTTPS(SSL)訪問簡單的 “Hello World” servlet 的吞吐量結果(在將每個連接的最大持久請求數量設置為不受限制之前和之後)。
圖 15. 將每個連接的請求數量設置為不受限制之前帶來的性能改進
c. 大分頁支持
一些平台支持建立一大塊相鄰的內存區,以便能夠使用比默認內存分頁大小更大的內存分頁。根據所使用的平台,大內存分頁大小可以從 4 MB (Windows) 到 16 MB (AIX) 不等,而默認分頁大小只有 4 KB。許多應用程序(包括基於 Java 的應用程序)經常能大分頁中受益,因為要管理的大分頁減少有助於降低 CPU 開銷。
要使用大內存分頁,首先需要在操作系統中定義並啟用它們。各平台的系統需求也相互不同,必須在可以啟用大分頁支持之前配置好它們。WebSphere Application Server Information Center 提供了在平台中完成此任務的詳細步驟:
調優 AIX® 系統
調優 Linux 系統
調優 Solaris™ 系統
調優 Windows 系統
在操作系統中完成配置之後,可以在 JVM 中啟動大分頁支持,方法是在管理控制台的 Servers => Application servers => server_name => Process definition => Java Virtual Machine 中指定 Generic JVM Arguments 設置的 -Xlp。需要注意,如果啟用了大分頁,則操作系統會留出一大塊相阾的內存區供 JVM 使用。如果剩余內存不足以處理其他正在運行的應用程序,則會換出分頁(即將內存中的分頁換出到硬盤上的分頁),這會顯著降低系統性能。
圖 16. 大分頁的性能改進
d. 禁用未使用的服務
禁用應用程序不需要的、未使用的服務可以改善性能。PMI 就是一個典型的例子。需要重點注意,必須啟用 PMI 以便查看本文之前記錄的指標並從性能審查程序獲取建議。雖然禁用 PMI 會移除查看此信息的功能,但它也提供了少許性能改進。可以為各應用服務器禁用 PMI,方法是在管理控制台中導航到 Monitoring and Tuning => Performance Monitoring Infrastructure (PMI)。
圖 17. 禁用 PMI 的性能改進
e. Web 服務器位置
IBM HTTP Server 等 Web 服務器通常用於在 WebSphere Application Server 部署中處理靜態內容,或提供工作負載管理 (WLM) 功能。在 V6 之前的 WebSphere Application Server 版本中,還需要借助 Web 服務器來有效處理數以千計的傳入客戶機連接,其原因歸結為客戶機連接與 Web 線程之間的 “一對一” 映像關系(之前討論過)。在 WebSphere Application Server V6 及更高版本中,NIO 和 AIO 的引入免除這些需求。對於使用 Web 服務器的環境,應該將 Web 服務器實例置於不同於 WebSphere Application Server 實例的專用系統上。如果某 Web 服務器所在系統上有一個 WebSphere Application Server 實例,則它們將有效共享有價值的處理器資源,從而降低配置的總體吞吐量。
我們將 IBM HTTP Server 與 WebSphere Application Server 放置在同一台本地機器上執行了 DayTrader 測試,然後又將 Web 服務器置於遠程專用機器上執行了第二次測試。表 5 顯示了 Web 服務器和應用服務器置於相同系統上時各進程點用的 CPU 周期百分比。從結果中可以看出,HTTP Server 進程占用了大約 25% 的 CPU 周期,這對應此測試中所使用的 4-CPU 系統中的 1 個 CPU。
表 5. HTTP Server 的 CPU 利用率 進程 CPU % WebSphere Application Server 66.3 IBM HTTP Server 26.2
圖18 比較了這兩個場景以及完全沒有 Web 服務器的情況下的吞吐量和響應時間。
圖 18. 使用或未使用 Web 服務器時的吞吐量
異步消息傳遞調優
目前為止,本文的側重點主要是 DayTrader 應用程序和 WebSphere Application Server 的核心 Web 服務和持久性方面。現在,我們將重點轉到 DayTrader 如何使用 JMS 組件來執行異步處理或交易訂單和監控報價變化。DayTrader 基准測試應用程序包含兩個可單獨啟用或禁用的消息傳遞特性:
異步訂單處理:異步訂單交易處理將由一個 JMS 隊列和一個 MDB 來處理。
報價一致性跟蹤:一個 JMS 話題,並且 MDB 將用於監控與股票交易訂單相關的報價變化。
消息傳遞配置有兩個主要調優選項會對性能造成顯著影響:消息庫類型和消息可靠性。除此之外,一種更加高級的、能實現額外性能改進的調優技巧是將事務日志和文件庫(如果可用)放置在速度較快的磁盤上。各主題以及相應的性能改進將在下面詳細討論。
討論要點。
消息庫類型
消息可靠性水平
將事務日志和文件庫移動到快速磁盤上
a. 消息庫類型
WebSphere Application Server 的內部消息傳遞提供者維持消息傳遞引擎“數據庫”的概念。數據庫充當由引擎處理的消息的持久存儲庫。在單服務器環境中創建了一個消息傳遞引擎之後,系統會創建一個基於文件的庫來作為默認數據庫使用。在 WebSphere Application Server V6.0.x 中,默認數據庫將由一個本地的 in-process Derby 數據庫提供。基於文件和 Derby 的數據庫非常適用於單服務器場景,但不能提供最高水平的性能、可伸縮性、可管理性或高可用性。要滿足這些需求,可以使用一個遠程數據庫數據暫存器:
本地 Derby 數據庫數據暫存器:通過此選項,可以使用一個本地 in-process Derby 數據庫來存儲操作信息以及與消息傳遞引擎相關的消息。雖然適用於開發目的,但此配置需要使用應用服務器中的寶貴 CPU 周期和內存來管理存檔的消息。
基於文件的數據暫存器:(默認)如果配置消息引擎使用基於文件的數據暫存器,則操作信息和消息將持久化到文件系統中,而不是數據庫中。其執行速度比本地 Derby 數據庫更快。並且,如果使用了快速硬盤,比如獨立磁盤冗余陣列(RAID),其執行速度可以與遠程數據庫相媲美。下面顯示的測試結果並未使用 RAID 設備作為基於文件的數據暫存器,並且未返回此額外改善。
遠程數據庫數據暫存器:在此配置中,遠程系統中的數據庫將充當消息引擎數據暫存器。這將釋放應用服務器 JVM 進程占用的之前用於管理 Derby 數據庫基於文件的暫存器的 CPU 周期,從而允許使用一個性能更加出眾的生產級數據庫服務器(比如 IBM DB2® Enterprise Server)。使用數據庫作為數據暫存器在技術方面的一個優勢是,一些 J2EE™ 應用程序可以共享 JDBC 連接,從而受益於單相提交優化。請參見關於通過共享連接獲取單相提交優化收益的更多信息。文件暫存器不支持這種優化。
DayTrader 使用這三種不同的消息暫存類型運行於 EJB 異步模式之下。在運行過程中,我們啟用了跟蹤規范 org.apache.geronimo.samples.daytrader.util.Log=all 來捕獲接收 TradeBrokerMDB 消息的所用的時間。在測量異步消息傳遞性能時,讓度量以異步 MDB 響應時間為基礎為非常重要的 —— 而不是實際的同步分頁響應時間。圖 19 中的結果表明,遠程數據庫數據暫存器能實現最佳性能,因為它提供了最短的 MDB 響應時間和最高的吞吐量。
圖 19. 消息暫存器類型性能比較
b. 消息可靠性水平
消息的可靠性對於任何消息傳遞系統來說都是一個非常重要的因素。WebSphere Application Server 消息傳遞提供者提供了 5 種不水平的可靠性:
盡可能保證非持久性(Best effort non-persistent)
極速非持久性(Express non-persistent)
可靠的非持久性(Reliable non-persistent)
可靠的持久性(Reliable persistent)
可以保證的持久性(Assured persistent)
持久消息始終會保存到某種形式的持久化數據暫存器中,而非持久化消息通常存儲在易變內存中。消息交付的可靠的和交付該消息的速度之間是一種權衡關系。圖 20 顯示了使用可靠性水平不同(可以保證的持久性和極速非持久性)的文件暫存器的兩種測試的結果。結果清楚地顯示,隨著可靠水平提高,處理消息的速度會變得更快。
圖 20. 消息可靠性水平的性能比較
c. 將事務日志和文件暫存器移動到快速磁盤
由於磁盤 I/O 操作開銷較大,因此將日志文件存儲在 RAID 這樣的磁盤上可以顯著改善性能。在大多數 RAID 配置中,將數據寫入到物理媒介中的任務將由多個驅動器共享。此技巧產生的結果是會更多地采用的並發的方式來訪問存儲以持久化事務信息,以便更快地訪問日志中的數據。
可以在管理控制台中設置事務日志目錄,方法是導航到 Servers => Application Servers => server_name => Container Services => Transaction Service。
在創建 SIBus 成員的過程中,可以使用 AdminTask addSIBusMember 中的 -logDirectory 選項,或者通過管理控制台 SIBus Member 創建面板來指定文件暫存器日志目錄(File store log directory)。
圖 21 顯示了兩種測試的運行結果:一個測試將事務日志和文件暫存器存儲在本地硬盤上,而另一個測試將它們存儲在一個 RAMDisk 上(這會從本質上將內存區作為硬盤對待,以實現更快的讀取和寫入操作)。運行測試時,我們使用了極速非持久性可靠性水平。結果表明,將日志存儲在快速磁盤上時,響應時間和吞吐量指標較高。
圖 21. 使用快速磁盤的性能改進
結束語
IBM WebSphere Application Server 的宗旨是能夠滿足應用程序不斷增加的需求,並且這些應用程序有各自的獨特特性、需求和服務。這種靈活性也承認了這樣一個事實:任意兩個應用程序都不會采用完全相同的的方式來使用應用服務器,同時也沒有一組調優參數可以為任意兩個不同的應用程序提供最佳的性能。
雖然 DayTrader 可能不同於您的應用程序,但判定采用何種調優的方法是相同的。關鍵是根據應用程序體系結構確定並專注於應用程序所使用的主要服務器組件和資源。通常而言,許多應用程序都可以通過調優以下三個核心區域實現一定程度的性能改進:JVM、線程池和連接池。其他一些可以調優的參數也能實現非凡的效果;但是,它們通常涉及應用程序所使用的具體 WebSphere Application Server 特性。
本文討論了這些可以調優的核心參數,以及其他一些能讓 DayTrader 應用程序獲益的選項。對於這些選項,我們都提供了找到它們的方法,提供了一些通用建議和要注意的權衡事項,並了指明了相關工具。圖 22 顯示了應用這些調優選項之後每個 DayTrader 運行時模式的總體性能改善:
JVM 堆大小
線程池大小
連接池大小
數據源語句緩存大小
ORB 通過引用傳遞
Servlet 緩存
不受限制的持久性 HTTP 連接
大分頁支持
禁用 PMI
圖 22. 應用調優選項之後的總體性能改善
從圖中可以明確看出,本文所述調優在 EJB 模式下實現了 169% 的改善,在 Session Direct 模式下實現了 207% 的改善,並在 Direct 模式下實現了 171% 的改善。這是相當可觀的改善,並且在其他應用程序中也可以實現類似的改善;但是,您必須記住最終的結果會因本文所述因素以及其他一些因素而異。
希望本文所討論的信息和工具能幫助您更加輕松地調優特定應用程序的應用服務器。