引言
J2EE 規范 對將 J2EE 應用程序打包成一個文件擴展名為 EAR(Enterprise Archive( 企業壓縮文檔))的文件進行了定義,並且規定這些應用程序彼此獨立。然而,該規范對 於如何最佳部署應用程序卻只字未提。您是應該選擇在每台應用程序服務器上只部署一個 J2EE 應用程序(EAR 文件)?還是應該在單獨一台應用程序服務器上部署多個 J2EE 應用 程序(EAR 文件)?
IBM® WebSphere® Application Server支持這兩種選擇。您應該選擇哪種方式 ?本文探討了針對這兩種選擇您需要考慮的許多問題。當您閱讀本文時,請記住:一個 EAR 文件可以包括一個或多個 WAR(Web 應用程序壓縮文檔(Web Application Archive) )文件(我們將單獨討論將若干個 WAR 文件打包成一個 EAR 文件的打包准則,本文不涵 蓋這方面的內容)。
性能
一般來說,一台機器上的進程(應用程序服務器、HTTP 服務器進程等)數越少,在這 台機器上發生內存交換、頁面調度或上下文切換的可能性就越小。我們期望的結果是操作 系統將投入較少的資源用於進程管理,從而使更多的系統資源能夠被用於處理應用程序工 作負載。這樣會改善應用程序性能。
請考慮有 20 個應用程序的情況;在這種情況下,您將創建 20 台應用程序服務器,每 個應用程序一台。如果每台服務器都有一個 256 MB 的 Java 堆,那麼這些應用程序服務 器所要求的內存將至少為 5 GB。在極端情況下,如果大量應用程序被部署到一個節點,這 些應用程序服務器將不得不被共享;否則,物理內存將被用光。對於這種情況,CPU 資源 也是一個限制因素,盡管通常只有在機器滿負載(被定義為 85% 的 CPU 正在使用中)時 (因為進程級的內務處理(housekeeping)任務會消耗大量的 CPU 周期),人們才會關注 CPU 資源。當然,通常只有當運行接近一台給定機器的內存極限或 CPU 極限時,進程管理 的開銷才會成為一個問題。幸運的是,為了顧及工作負載峰值(spike)或停機(outage) ,大多數組織采用的標准做法是以 50% 的 CPU 利用率運行生產服務器,所以這種極端情 況很少發生。
作為一個示例,請考慮一下這個簡單的測試案例:兩個應用程序在各種不同負載下運行 ,它們先是各自被部署在一台應用程序服務器上,然後被部署在單獨一台應用程序服務器 上。所有的測試都在具有 2 GB RAM、運行 iPlanet 6.01 和 WebSphere Application Server 4.03 高級版的 2 CPU HP-UX 服務器上運行。Oracle 8.1.7 數據庫單獨使用一台 服務器。
應用程序 吞吐量(請求數/秒)- 兩台應用程序服務器 吞吐量(請求數/秒)- 一台應用程序服務器 應用程序 A ? 50% CPU 31.15 36.97 應用程序 B ? 50% CPU 48.86 53.57 應用程序 A -> 85% CPU 38.22 45.02 應用程序 B -> 85% CPU 57.66 64.58圖 1.
從上面的測試案例中可以看到,只用一台應用程序服務器運行兩個應用程序會使性能得 到顯著改善,改善程度從 9.6% 到 18.7% 不等。盡管每個應用程序都呈現對性能有正面影 響,但因每個應用程序施加的工作負載不同,所以改善程度也有所不同。應用程序 A 針對 每個請求執行幾次數據庫選擇以及一次更新,而應用程序 B 針對每個請求則只執行一次或 兩次數據庫選擇,且每隔 8 到 10 個請求進行一次更新。在任何情況下,對於那些性能很 重要並且帶有大量應用程序的環境來說,減少應用程序服務器數量可以顯著地改善性能。 在操作系統資源相同的條件下,將應用程序結合到共享的應用程序服務器中可以得到更好 的應用程序性能。不過,每次都要進行測試以確保對於您的環境而言確實能夠提高性能, 這是很重要的。
性能測試和問題確定
要確實獲得單獨一台應用程序服務器所能提供的可能的性能優勢,您應該用兩種方式測 試性能和可伸縮性。第一種方式,測試每台應用程序服務器只有一個應用程序的情況,以 驗證一個給定的應用程序的性能和可伸縮性,從而消除特定於該應用程序的任何應用程序 瓶頸。第二種方式,同將被部署到同一台應用程序服務器上的所有其他應用程序一起進行 測試。另外,請記住:一次測試多個應用程序代表的是一種比分別測試各個應用程序更復 雜的情況。負載測試需要多個腳本,每個要同時運行的應用程序一個腳本。要徹底解決共 享應用程序服務器的應用程序可能引發的問題,系統地測試產品化之前的多個系統是至關 重要的。
如果您選擇在單獨一台應用程序服務器上部署多個應用程序並且出現了性能問題,那麼 確定哪個應用程序出了問題就更加困難。幸運的是,您可以使用 WebSphere Application Server 提供的許多性能監視工具,還可以使用第三方提供的用於這一目的的工具。
應用程序可伸縮性
在某些情況下,應用程序開發者可能會選擇不按照 Harvey Guther 在 WebSphere Application Server Development Best Practices for Performance and Scalability 中概述的應用程序開發最佳實踐去做。由於 HTTP 會話對象的大小,您在選擇如何部署時 可能會受到限制。有些讀者可能碰到過這樣的應用程序,這些應用程序中的 HTTP 會話對 象的大小不僅要求在每台應用程序服務器上只部署一個應用程序,還要求創建多個克隆。 在極端情況下,當會話對象的內存要求用光甚至超過了可用的 JVM 堆的時候,這樣做是有 必要的。例如,對於一個 1.0 MB HTTP 的會話對象和 1,000 個連接的用戶,僅會話對象 的內存要求就是 1.0 GB(1000 x 1.0 MB)。當然,您可以更改內存中存儲的會話數量, 但會話對象將溢出內存或者被寫入數據庫,這取決於配置。這兩種選擇都會影響性能,尤 其是在會話對象很大的情況下。其他的應用程序瓶頸可能還要求將多台應用程序服務器( 克隆)用於單個應用程序,這僅僅是為了滿足可伸縮性和性能方面的要求。
操作控制權和維護
當您選擇在單獨一台應用程序服務器上運行兩個 J2EE 應用程序(例如應用程序 A 和 應用程序 B)時,您應該考慮下列問題。
同一個人有停止在應用程序服務器上運行的所有應用程序的權限嗎?盡管 WebSphere Application Server 使您能夠從管理控制台和 wscp 啟動和停止一台應用程序服務器內部 的各個應用程序,但是,一個組織仍然需要考慮如何分配操作控制權。
有些改動(例如安全性改動)需要重新啟動應用程序服務器才會生效。如果兩個或更多 個應用程序共享一台應用程序服務器,這會引起相互沖突的需要。此外,同一台應用程序 服務器上的所有應用程序都以相同的操作系統身份運行。這樣就存在安全性隱患,因為與 一台應用程序服務器上的應用程序相關聯的文件許可權是歸這個操作系統身份所有的。在 這種情況下,您無法保護與一個應用程序相關聯的文件,使這些文件不被這台應用程序服 務器上的其他應用程序訪問,因為這些應用程序共享相同的操作系統特權。如果您不能接 受這種情況,那麼您將需要為每個應用程序建立一台應用程序服務器以提供安全性保護。
一個組織打算怎樣處理應用程序升級?要注意的事項包括對應用程序構建的控制以及對 應用程序服務器過程的控制。因為 EAR 不僅是一個部署時(deploy-time)組件,而且還 是一個構建時(build-time)組件,所以情況還可能取決於誰可以觸發構建行為。雖然通 常都建議 EAR 應是完全獨立的,但是事實上並不是必須如此,而且有許多 EAR 並非完全 獨立的情況。一個 EAR 中的 EJB 或 servlet 依賴於另一個 EAR 中的 EJB 並可以通過全 局 JNDI 名稱空間進行訪問,這並不罕見。如同前面所提到的,WebSphere Application Server 使您能夠停止和啟動各個應用程序,但是在某些情況下,一個應用程序升級可能要 求您啟動和停止整台應用程序服務器。一個組織是願意停止或啟動整台運行著多個應用程 序的應用程序服務器來執行更新呢?還是希望能一個應用程序一個應用程序地執行更新呢 ?如果每個應用程序有一台應用程序服務器,這樣做就會更容易,不過,對於一台應用程 序服務器上有多個應用程序的情況,也可以做到這一點。
應用程序如果要求用戶在 JVM 類路徑中添入某些項或者要求用戶設置全局 JVM 系統屬 性,那麼應用程序本身就有可能引入相互沖突的需要。選擇類裝入器可見性也會導致部署 不兼容性問題,例如在應用程序采用單一的 singleton 時使用服務器可見性。在單個 JVM 中按這樣的體系結構部署兩個或更多個應用程序不可能有服務器可見性。Keys Botzum 在 J2EE Packaging and Common Code中更詳細地討論了如何部署和打包應用程序,Rick Robinson 在 Developing and Deploying Modular J2EE Applications with WebSphere Studio Application Developer and WebSphere Application Server中更詳細地討論了如 何選擇類裝入器。
在極端情況下,編寫得很糟糕的應用程序會導致 JVM 掛起或發生故障,並因而影響其 他表面上不相關的應用程序。考慮一下這種情況:一個編寫得很糟糕的應用程序啟動了許 多線程,或者消耗了許多內存或其他共享資源(如數據庫連接)。在這個示例中,有幾種 可能的情況,一個應用程序可以接管一台應用程序服務器而讓其他的應用程序處於饑餓狀 態。同樣,性能特征需要兼容。事實上,調優本文的性能測試部分所使用的兩個應用程序 花了本文作者相當多的時間和精力。經過系統的測試和細心的規劃,您僅可以識別和修復 應用程序或資源沖突。
故障轉移和工作負載管理
應用程序部署還取決於故障轉移要求。WebSphere Application Server 4.x 通過服務 器組提供故障轉移和工作負載管理定義。服務器組支持將多個應用程序服務器組成群集。 結果,您將只想把應用程序分組到同一個應用程序服務器中,或分組到有類似的可伸縮性 和/或故障轉移需要的服務器組中。
請考慮下面的圖 2 中描述的部署備選方案。哪一個方案是供故障轉移使用的?
圖 2.
在這種方案中,每台應用程序服務器上只有一個應用程序,一台應用程序服務器發生故 障將導致與該應用程序服務器相關聯的應用程序的服務丟失。請記住:大多數環境都意識 到上面描述的兩種部署選擇都不是真正容錯的,因為單獨一台物理服務器的丟失會造成停 機。下面的圖 3 中描述了一種更典型的方案。這種部署方案將物理服務器作為單個故障點 除去。如需更多關於如何使用 WebSphere Application Server 規劃和實現高度可用的環 境的信息,請參閱 Modjeski 等人著的白皮書 Failover and Recovery in WebSphere Application Server Advanced Edition 4.0。
圖 3.
結束語
雖然本文作者支持在多個 J2EE 應用程序之間只共享一台 JVM/應用程序服務器,但是 在許多情況下,這樣可能並不切合實際。對於許多組織來說,在每台應用程序服務器上部 署一個應用程序是一種更高效的方式,把時間集中花在對各個應用程序性能進行最優化上 。另外,在某些情況下,或者出於操作需要,或者由於應用程序設計,應用程序會要求具 有它自己的 JVM。
一般來說,任務關鍵的應用程序或大型應用程序可能出於以上原因會想要在它們自己的 JVM 中部署,而較小的或不那麼重要的應用程序或相互聯系的應用程序(人力資源應用程 序,尤其是那些共享相同類型的後端的應用程序)可能想要共享 JVM。例如,所有的 Siebel 應用程序可能想要共享一個 JVM,所以如果 Siebel 出了故障,則只有這些應用程 序受到影響。
多個 J2EE 應用程序共享一些應用程序服務器通常能改善性能,尤其是對於有許多應用 程序的大型環境來說。然而,與每台應用程序服務器運行一個 J2EE 應用程序相比,這是 以操作靈活性為代價的。情況經常如此,要涉及到許多折衷,作出什麼選擇將取決於組織 打算怎樣管理它們的應用程序、它們的安全性要求、它們的職員在應用程序管理和應用程 序設計方面的技能、應用程序可用性要求以及它們的過程成熟度。