引言
在構建強大而靈活的可擴展 J2EE 應用程序時,您需要考慮一些相關因素。一個重要的注意事項是允許應用程序在集群環境中高效地運行。本文討論了在 WebSphere Application Server 集群環境中設計基于 Web 的應用程序時需要考慮的事項。
WebSphere Application Server 集群機制允許將整個應用服務器(包括 EJB 容器、EJB、Web 容器、Web
模塊和 Servlet)作為一個集群進行復制。集群提供了工作負載管理以及 URL 和 EJB
請求故障轉移。各個集群成員是該集群中完全相同的副本,它們可以運行于 WebSphere
單元中的節點。集群可以位于相同或不同的節點。Network Deployment
單元可以不包含集群、或者包含多個集群,這取決于該單元的管理需求。有關 WebSphere Application Server
集群的信息,請參見 WebSphere Application Server 聯機幫助。
集群拓撲有兩種類型,垂直集群或水平集群。垂直集群在同一節點或物理計算機上具有多個集群成員。水平集群在計算單元中的很多計算機的多個節點上都具有集群成員。本文將討論如圖 1 所示的水平集群拓撲。
圖 1. 集群拓撲
我們將討論在設計基于 Web 的應用程序時的三個注意事項:
- 實現應用程序文件同步:我們將研究常用的機制是什么,以及如何利用 WebSphere Application Server 6.0 的新特性來實現它。
- 序列化會話對象:因為會話中包含的對象將在集群內的節點中進行同步,所以必須實現它們的 serializable 接口。本文提供了一個示例,以介紹如何強制完成這項工作。
- 使用動態緩存:我們將討論如何使用 WebSphere Dynamic Cache 和 Data Replication Service 在集群中共享 Java™ 對象。
實現應用程序文件同步
在企業應用程序的生命周期中,通常可以通過應用修復程序、添加新的 Web 內容或更新應用程序行為來對已部署的應用程序進行更新。一般來說,應用程序提供了允許用戶上傳在服務器端更改或創建的文件的用戶界面。
將下面的場景作為一個示例:用戶希望更新 Web 站點徽標圖像文件,并且將原始文件作為 .war
文件應用程序的一部分進行存檔。該應用程序提供了相關的功能和用戶界面,以便用戶完成這項任務。然后,用戶選擇一個新的圖像作為 Web
站點的新徽標,并且上傳該文件。系統使用新的文件替換原始的文件,并且當用戶再次訪問他的 Web
站點時,可以看到相應的更改。在單節點環境的應用服務器中,所有這些工作都可以順利進行。然而,在集群環境中卻存在一些問題。
在集群環境中,如圖 2 所示,WebSphere Application Network Deployment 服務器中的
Deployment Manager 將接收到用戶的上傳請求,然后該請求被發送到 Node A。Node A
將執行相應的業務邏輯并使用本地文件系統中的新圖像文件替換原始圖像文件。然而該集群中其他的成員并不清楚這項更改,其本地副本并沒有得到更新。因此,該
集群中各個成員之間的這個圖像文件就出現了不一致的情況。如果 Node A 因為致命錯誤而停機,而 Node B
接收到了該請求,那么仍將使用原始的 Web 站點徽標。看上去客戶似乎丟失了他所做的更改。
圖 2. 集群環境中不一致的文件
這意味著,當應用程序運行于 WebSphere Application Server
時,需要在集群成員之間同步配置文件、二進制文件和資源文件。有一種機制可以處理上述問題。解決方案是使用共享的文件系統(例如,NFS)或共享的數據
庫。在這個解決方案中,所有經過更改或更新的文件都位于同一個共享文件系統或同一數據庫中。對于共享的文件系統,所有應用程序都使用相同的位置,因此對于
這些應用程序來說,任何文件更改都是可見的。對于共享的數據庫,應用程序可以從數據庫中獲得相應的更改。
上述解決方案的缺點包括:
- 共享的文件系統和數據庫導致一個新的單點故障。
- 它增加了編程和配置工作的復雜性。
- 它引入了一個新的性能瓶頸。
另一個解決方案是使用細粒度 WebSphere Application Server 應用程序管理
API,在集群的各個成員之間實現文件同步。WebSphere 6.0 中提供了這一特性。WebSphere 6.0
中包含許多改進,從而使得應用程序的部署更加容易并且更加高效。有關詳細信息,請參見 WebSphere Application Server 信息中心。其中一個重要的改進是允許向系統提供部分經過更改的應用程序代碼。不需要停止當前正在運行的應用程序。
WebSphere 6.0 還提供了靈活的應用程序文件管理。它允許應用程序通過以下方式進行更新:
- 替換整個應用程序(例如,整個 .ear 文件)。
- 替換、添加或刪除應用程序中的單個模塊(例如,.war、EJB.jar 或 .rar 文件)。
- 替換、添加或刪除單個文件。
- 替換、添加或刪除多個文件。
在對集群中的某個成員上的應用程序文件進行更新之后,將使用另一個新的特性 Rollout Update 對集群中各個成員的文件進行同步。它通過以下方式對應用程序進行更新:
- 保存更新的應用程序配置。
- 停止給定節點上所有的集群成員。
- 通過同步配置和重新啟動該節點上停止的集群成員來更新該節點上的應用程序。
讓我們回到前面關于 Web 站點徽標更新的示例。在這個場景中,徽標的更新和同步對于用戶來說應該是透明的,無需 WebSphere
管理員進行人工干預。這就意味著,應用程序必須控制應用程序的更新,如替換存檔于 ear
文件中的原始文件,并在集群的成員之間執行文件同步。您可以通過調用 WebSphere 提供的 Java Management
Extensions (JMX) 接口來完成這項任務。JMX 是一項 Java 應用程序資源管理標準。有關 JMX 的詳細信息,請參見 JMX Web 站點。圖 3 顯示了使用細粒度更新特性進行文件更新和同步的流程。
圖 3. 使用細粒度特性更新和同步文件
應用程序在接收到用戶上傳的文件之后,它將調用 File Updater 以構造增量 EAR 文件。這個增量 EAR
文件是一個存檔文件,它具有與完整的應用程序 ear 文件相同的結構。增量 EAR 文件和完整的應用程序 EAR 文件之間的區別在于,該增量
EAR 文件僅包含要進行更新的文件。File Updater 將構建這個增量 EAR。它可以是封裝了增量 EAR 生成邏輯的簡單 Java
類,或者是添加了驗證邏輯和生成文件的相關復雜組件。
序列化會話對象
使用集群方式的應用程序可以提高系統的可靠性和可用性。然而,這也引入了一些挑戰,如會話管理。HTTP
會話是包括用戶特定信息的集合。從用戶開始訪問到用戶最后一次訪問結束的這段時間內,由容器對會話進行維護。會話由一系列的會話屬性組成。事實上,這些屬
性都是由系統或開發人員創建的 Java 對象。
在集群環境中,開發人員必須清楚,HTTP 會話可能運行于多個 JVM 中。這些會話屬性應該在每個 JVM 中保持一致。否則,當應用程序運行于不同的節點時,相同的輸入可能產生不同的結果,這是因為與用戶相關的數據在這兩個節點中不一致。
WebSphere 為集群方式的應用程序提供了實時的、完全一致的數據共享。然而,前提是必須對所有共享的屬性進行序列化和反序列化。當您將
Java 對象放入到會話中并希望在所有的節點之間共享該對象時,需要將這個 Java 對象聲明為一個 serializable
接口。下面的代碼顯示了在將對象放入到會話屬性時進行的驗證工作。
public class MySession{
public static void addObjectToSession(HttpServletRequest req, String key,
Object value)
{
HttpSession session = req.getSession(true);
if(value instanceof Serializable)
session.setAttribute(key, value);
else
throw new NonSerializationException ();
}
public MySession()
{
}
}
|
在上面的示例中,您創建了一個名為 MySession 的新類,用來將對象添加到會話中。您可以通過調用
addObjectToSession() 方法來添加它。首先應該檢查該對象是否實現了 serializable
接口。如果已經實現,可以隨后將這個對象添加到當前的 Http 會話中。否則,將會出現
NonSerializationException。有些時候,在運行于另一個 JVM
中時,會話屬性中包含的信息無關緊要,如文件的絕對目錄。在這種情況下,通過將其聲明為瞬態屬性可以使得這些字段不使用集群方式。
使用動態緩存
如上所述,將應用程序數據保存在中央數據庫中可以確保在集群環境中寫入和一致地讀取數據。這種解決方案的缺點是,數據庫服務器引入了新的單點故障
(SPOF),并且不適合那些需要高性能的應用程序。另一種解決方案是使用 WebSphere Dynamic Cache 和 Data
Replication Service
(DRS)。您可以在基于內存的對象緩存的方式下,通過共享整個集群中某些服務器上的對象,來實現這個解決方案。圖 4 顯示了帶 Data
Replication Service 的 WebSphere Dynamic Cache 的體系結構。
圖 4. WebSphere 動態緩存概述
WebSphere Dynamic Cache 是面向 J2EE 體系結構和緩存對象的解決方案。表示層中 Web 服務、Servlet
和 JSP 的輸出、WebSphere 命令類以及 Java 對象都可以使用應用程序編程接口 (API)
進行緩存,或者聲明一些緩存策略并將其添加到應用程序中。
Data Replication Service (DRS) 是用于復制數據的 WebSphere Application Server
內部組件。DRS 使得集群中的各個服務器都可以使用會話管理、動態緩存和無狀態會話 Bean 的數據。動態緩存可以利用應用服務器中的 DRS
在集群的各個服務器中復制緩存的數據。在集群范圍內傳輸數據失效通知,以保持數據的一致性和有效性。圖 5 顯示了如何使用動態緩存和 DRS
在集群中共享應用程序數據。
圖 5. 在集群中共享對象
首先,應用程序運行于 Server One,并通過調用 DistributedMap API 將 Object A
放入其本地緩存中。通過合適的配置,DRS 可以在整個集群范圍內復制緩存的對象并保持緩存數據的一致性。因此,將 Object A 復制到
Server Two 的本地緩存。當應用程序運行于 Server Two(假如 Server One 遇到問題或根據負載平衡策略將事務提交到
Server Two)時,應用程序可以從 Server Two 的本地緩存中獲得 Server One 的 Object A。
WebSphere Application Server 通過使用緩存實例存儲和管理緩存的 Java
對象。緩存實例還可以用于對相關的對象進行邏輯分組。特定實例的緩存中存儲的對象不會受到其他緩存實例的影響。如上所述,DistributedMap
公共接口使得應用程序可以直接訪問緩存實例。
應用程序可以存儲和檢索任何實現了 java.util.Map 接口的對象。您所緩存的任何其他 Java 對象都必須實現
java.io.Externalizable 或 java.io.Serializable 接口。集群中的服務器可以通過使用其 JNDI
名稱來訪問緩存實例。這些服務器必須位于同一個復制域。下面的代碼示例顯示了應用程序如何通過其 JNDI
名稱查找緩存實例,將對象放入緩存實例中,并稍后對其進行檢索。
Import javax.naming.InitialContext;
Import com.ibm.websphere.cache.DistributedMap;
...
InitialContext context=new InitialContext();
DistributedMap map=(DistributedMap)context.lookup("cache/example_cache_instance");
map.put("cache_id", yourJavaObject);
YourJavaObject obj=(YouJavaObject)map.get("cache_id");
|
結束語
本文討論了設計運行于 WebSphere
集群環境的應用程序時需要考慮的三個方面。存儲于文件系統的應用程序數據應當在每個集群服務器中保存一致。針對這個需求的解決方案是使用共享的文件系統或
共享的數據庫。使用細粒度文件更新特性,您可以在集群范圍內擁有更靈活的應用程序文件,并避免引入新的單點故障。會話管理是 Web
應用程序的一個重要的考慮事項。您應該考慮進行對象序列化和反序列化,以便在集群范圍內進行共享。您可以使用自已定義的類將對象封裝到會話中,然后同時執
行驗證。您還可以通過使用 WebSphere Dynamic Cache 和 Data Replication Service
實現集群范圍內應用程序數據的共享,這將顯著地提高應用程序的性能。
參考資料
學習
獲得產品和技術
討論
WebSphere Application Server discussion 論壇
posted on 2007-11-02 11:15
前方的路 閱讀(1029)
評論(0) 編輯 收藏 所屬分類:
軟件架構 、
Web應用服務器