本文將討論GlassFish Version2的集群功能,幫助您將自己的應用程序部署在GlassFish集群上。
Sun Java System Application Server 9.1是開放源碼GlassFish version 2應用服務器的Sun發行版。本文使用GlassFish version 2這個名稱表示這兩者。
基本概念
應用服務器中的集群可增強可伸縮性和可用性,而這兩者是彼此相關的。
為了提供高可用性的服務,軟件系統必須具有以下功能:
系統必須能夠創建並運行服務提供的實體的多個實例。在應用服務器中,服務提供的實體是在集群中運行的Java EE應用服務器實例,服務是部署的Java EE應用程序。
為了處理增加的服務負載,系統必須能夠在集群中添加應用服務器實例,從而適應更大的部署。
如果集群中的一個應用服務器實例發生了故障,那麼必須能夠故障轉移到另一個服務器實例,使服務不會中斷。盡管服務器實例或物理機器的故障會使服務的總體質量有所下降,但是在高可用性環境中服務完全中斷是不可接受的。
如果某個進程要修改用戶會話的狀態,那麼會話狀態必須被持久化,能夠在進程重新啟動之後恢復。最簡單的方法是維護一個可靠的會話狀態副本;如果進程終止了,那麼在進程重新啟動時可以恢復會話狀態。這個原理與高可用性RAID存儲系統的原理相似。
這些要求導致系統犧牲高效率來換取高可用性。
為了支持可伸縮性和高可用性,GlassFish應用服務器提供以下服務器端實體:
服務器實例(Server Instance) – 服務器實例是一個Java EE 服務器進程(GlassFish應用服務器),該進程運行著各種Java EE應用程序。根據Java EE規范的要求,必須針對要運行的各個子系統對每個服務器實例進行配置。
節點代理(Node Agent) – 節點代理是一個代理進程,它在運行服務器實例的每個物理主機上運行。當 本文後面 描述的Domain Administration Server(DAS)發出指示時,節點代理將管理服務器實例的生命周期。
集群(Cluster) – 集群是一個邏輯實體,它決定組成集群的服務器實例的配置。集群的配置常常意味著集群中的所有服務器實例有相同的配置。管理員通常將集群看做一個單一實體,並使用GlassFish Admin Console或命令行界面(CLI)管理集群中的服務器實例。
可以在安裝GlassFish時創建節點代理、服務器實例和集群,見 本文後面的說明。集群和實例被組織成管理域(administrative domain),這由Domain Administration Server(DAS)控制。
域管理體系結構
GlassFish集群體系結構的核心概念是管理域(administrative domain)。管理域表示管理員或管理員組的訪問權限。下圖給出域管理體系結構的概況(只包含一個域)。
圖1. 域管理體系結構
管理域是一個具有雙重性的實體:
在由開發人員使用時,它可以提供一個特性完整的Java EE進程,可以在其中運行應用程序和服務。
在真實的企業部署中使用時,它可以提供一個專門用於配置和管理其他進程的進程。在這種情況下,管理域將采用Domain Administration Server(DAS)的形式,並且只能用於管理目的。
在文件系統中,管理域由一組配置文件組成。在運行時,它是一個對本身、獨立的服務器實例、集群、應用程序和資源進行管理的進程。
總的來說,高可用性安裝需要集群,但是不一定需要獨立的服務器實例。GlassFish應用服務器提供同構的集群,讓我們能夠把每個集群作為單一實體來管理和修改。
如圖所示,每個域有一個Domain Administration Server(DAS),DAS用來管理這個域中的Java EE服務器實例。圖中央的Administration Node支持DAS。應用程序、資源和配置信息存儲在非常接近DAS的地方。由DAS管理的配置信息稱為配置中心存儲庫(central repository)。
每個域進程必須在一個物理主機上運行。在運行時,域本身表現為一個DAS。同樣,每個服務器實例必須在一個物理主機上運行,並需要一個Java虛擬機。在運行服務器實例的每台機器上都必須安裝GlassFish應用服務器。
圖右邊顯示兩個節點:Node 1和Node 2,它們各自包含兩個GlassFish服務器實例。
每個節點代理控制它的機器上一個給定域中配置的實例的生命周期。每個生命周期由DAS根據管理員的請求進行管理。DAS將每個實例的實際生命周期管理委派給對應的節點代理。節點代理是一個輕型的進程,它本身並不運行Java EE應用程序。
除了控制實例的生命周期之外,節點代理還監視(“watchdogs”)它所負責的服務器實例。如果服務器實例發生故障,它的節點代理會重新啟動它 — 不需要管理員或DAS干預。
圖1左邊顯示幾個管理客戶機。DAS中的管理基礎結構基於Java Management Extensions(JMX)技術。DAS中的基礎結構符合JAX規范的instrumentation級別,並以Managed Beans(MBeans)的形式使用管理信息(MBeans是代表要管理的資源的Java對象)。
因為MBeans符合JMX標准,所以可以用任何遠程的標准JMX客戶機(比如隨Java SE 5.0發行的JConsole)浏覽它們。圖1所示的內置客戶機使用JMX API來管理域。這些客戶機需要具有管理特權才能管理域。管理客戶機包括:
Admin Console – Admin Console 是一個用來管理中心存儲庫的基於浏覽器的界面。中心存儲庫提供DAS級的配置。
命令行界面 – asadmin命令提供與Admin Console相同的功能。另外,有一些操作只能通過asadmin執行,比如創建域或創建節點代理。如果沒有DAS,就不能運行Admin Console,而這意味著必須要有域和節點代理。asadmin命令提供建立這個體系結構的方法。
IDE – 圖中顯示一個JSP(JavaServer Page)編輯器的快照,它是NetBeans IDE的一部分。NetBeans IDE這樣的工具可以在開發期間使用DAS連接並管理應用程序。NetBeans IDE還支持集群模式部署。大多數開發人員在一個域和一台機器上工作,這稱為開發人員配置(developer profile)。在開發人員配置中,DAS本身作為所有應用程序的主機。
Sun Provisioning Server – Sun Provisioning Server用來在經過基本配置的機器上安裝和配置DAS。例如,假設要在一個大型數據中心中添加一台新機器。在這種情況下,會在機器上安裝操作系統,然後安裝所需的所有軟件產品。在此之後,可以創建一個節點代理,根據需要,還可以創建一個DAS。最後,啟動節點代理,將這台機器合並到現有的域中。Sun Provisioning Server可以完成所有這些任務,避免管理員在新機器上執行手工安裝。
集群體系結構
圖2按照以運行時為中心的視角描述GlassFish集群體系結構。這個圖強調體系結構的高可用性方面。圖2中沒有顯示DAS,節點和它們的應用服務器實例組合在一起,形成集群的實例。
圖2. 集群體系結構概況
在圖2的頂部,顯示各種傳輸協議(HTTP、JMS、RMI-IIOP),它們通過一個負載平衡層與集群的實例通信。定制的資源(比如企業信息系統)通過Java連接器體系結構中的資源適配器連接負載平衡器。可以跨集群對所有傳輸協議進行負載平衡,這可以提高可伸縮性,而且可以通過為單點故障提供冗余可用單元實現容錯策略。
圖的底部是一個High-Availability Application State Repository,這是會話狀態存儲的抽象。這個存儲庫存儲會話狀態,包括HTTP會話狀態、有狀態EJB會話狀態和單點登錄信息。可以通過內存復制或數據庫方式存儲這些狀態信息。
替代High-Availability Database的技術
在歷史上,Sun Microsystems曾經為應用服務器提供一種基於High-Availability Database(HADB)技術的健壯的高可用性解決方案。HADB為維護會話狀態信息提供百分之99.999(“5個9”)的可用性。但是,它的實現和維護成本相當高,而且盡管可以免費獲得,但是在開放源碼版本中沒有提供它。
為了給開放源碼的GlassFish應用服務器提供一種輕型的開放源碼替代技術,在GlassFish version 2中提供了內存復制特性。內存復制依靠集群中的實例將另一個實例的狀態信息存儲在內存中,而不是存儲在數據庫中。但是,HADB解決方案仍然是可用的,而且在許多環境中是首選方案。
集群中的內存復制
對於在內存中維護狀態信息的與GlassFish兼容的容錯系統,需要幾個特性。系統必須為HTTP會話狀態、單點登錄狀態和EJB會話狀態提供高可用性。另外,它必須與現有的基於HADB的體系結構兼容。
內存復制特性利用GlassFish的集群特性,提供HADB策略的大多數優點,而安裝和管理開銷卻小得多。
在GlassFish應用服務器中,集群實例組織成一個環形拓撲結構。環中的每個成員將內存狀態數據發送給環中的下一個成員(即它的復制伙伴),並接收來自前一個成員的狀態數據。當在任何成員中更新狀態數據時,數據會沿著環復制。圖3給出這個拓撲結構的簡化形式。
圖3. 集群拓撲結構
拓撲結構形成環形的方式由實例名稱的字母表次序決定。所以,如果實例名稱像圖3中這樣,那麼Instance 1將向Instance 2復制,Instance 2向Instance 3復制,以此類推。
典型的集群拓撲結構見圖4。在這個圖中,顯示的實例駐留在不同的物理機器上。將Instances 1和Instances 3放在一台機器上,將Instances 2和Instances 4放在另一台機器上,這可以提高可用性。如果其中一台機器發生災難性故障,那麼另一台機器上會保留所有數據(按照原來的形式,或者作為故障機器上實例的副本)。
圖4. 典型的集群拓撲結構
典型的故障轉移場景
GlassFish應用服務器的設計方式讓負載平衡器層在發生故障時不需要特殊信息就能夠執行負載平衡。例如,假設負載平衡器將一個會話分派給Instance 1,當Instance 1發生故障時,它不需要知道應該將會話分派給Instance 2。負載平衡器可以向集群中的任何實例發送一個故障轉移請求,這種情況常常稱為位置透明性。在集群中對故障進行響應。當負載平衡器將一個會話重新分派給一個正在工作的實例時,如果需要的話,這個實例會從另一個實例獲得它需要的會話信息。
來自負載平衡器的故障轉移請求屬於兩種情況之一:
第一種情況:接收故障轉移請求的實例已經存儲會話數據的副本。在這種情況下,實例獲得會話的所有權並繼續處理。
第二種情況:接收故障轉移請求的實例沒有所需的會話數據副本。在這種情況下,實例廣播一個self-addressed-stamped-envelope(SASE)形式的請求來請求數據。擁有數據副本的實例將數據傳輸給請求者,並在收到確認消息(表示已經成功地接收了數據)之後刪除它的副本。這個數據交換過程是通過 JXTA (Juxtapose)技術完成的。
圖5 給出更詳細的集群結構。左邊是負載平衡層,它可能在一個web服務器上。在每個服務器實例中,一個本地緩存存儲HTTP會話信息,這個緩存被復制到下一個實例的復制緩存。
圖5. 帶負載平衡器的典型集群拓撲結構
圖6說明故障轉移的第一種情況,在這種情況中重新分派的服務器實例可以直接訪問會話狀態數據。在圖中,Instance 1發生故障,負載平衡器的服務請求被分派給Instance 2,而Instance 2包含所需的會話狀態信息的副本。
圖6. 故障轉移,第一種情況
圖7說明故障轉移的第二種情況,在這種情況中負載平衡器層將會話重新分派給一個服務器實例,但是這個實例無法直接訪問會話狀態數據。在圖中,Instance 4發現它沒有所需的會話狀態數據,因此向集群中的其他實例廣播一個SASE請求來請求數據。這個請求用黃色箭頭表示。
圖7. 故障轉移,第二種情況
一個實例(圖7中的Instance 2)發現它的復制緩存包含所需的數據,就對這個SASE請求進行回復。Instance 2將會話數據的所有權轉交給Instance 4,然後Instance 4就開始為這個會話服務。
當一個實例使用數據副本為會話服務時(無論是第一種情況,還是第二種情況),首先要檢查數據副本,確保它是正確的版本。
集群動態變形
當集群中的一個實例發生故障或者根據管理員的指示離線時,集群的拓撲結構就需要改變。
在我們的示例中,因為Instance 1發生故障,所以必須改變集群的拓撲結構來維持會話緩存復制過程。在圖8中,Instance 2和Instance 4發現Instance 1消失了。因為Instance 1發生故障,所以與它的通信由於I/O異常而失敗。如果一個實例是根據指示關閉的,那麼JXTA技術會發送消息,指出Instance 1已經關閉。
圖8. 集群發現發生故障的實例
在發現Instance 1消失之後,Instance 4會選擇一個新的復制伙伴,見圖9。Instance 4取消原來的連接並建立到Instance 2的連接。集群現在從4個服務器實例縮減到3個。
圖9. 集群動態變形
注意,在會話活動量相同的情況下,比較小的集群中的每個實例現在要負擔更多的工作。在進行資源規劃時,還要考慮到內存復制會使用堆內存。為了提供高可用性,每個實例的內存必須留有足夠的裕量,以便應付集群收縮的情況。
當一個實例加入(或重新加入)集群時,發生本質上相反的過程。當集群中的新實例從負載平衡層接收請求時,這個實例廣播一個尋找復制伙伴的請求,選擇一個復制伙伴,拓撲結構會自動調整來接納這個新實例。
Group Management Service
Group Management Service(GMS)提供關於集群和它的成員實例的動態成員關系信息。它的設計借鑒了 Shoal項目 的許多思想,Shoal是一種基於Java技術的集群框架。GMS也是基於JXTA技術的。
GMS管理GlassFish中的集群變形事件,根據成員加入、成員正常關閉或成員故障等事件進行調整。內存復制通過GMS用必要操作響應這些事件,提供連續的服務可用性。
在GlassFish應用服務器中,使用GMS監視集群的狀態並支持內存復制模塊。
總之,GMS支持以下功能:
集群成員關系變化通知和集群狀態
整個集群范圍內的或成員之間的消息傳遞
面向恢復的計算,包括恢復成員選擇、故障保護和針對多個故障的恢復鏈
分布式緩存,這是一個適合交換集群成員關系消息的輕型實現
一個服務提供者接口(SPI),用來加入組通信提供者;默認的提供者是基於JXTA技術的
計時器遷移 – 如果必要的話,GMS會選擇一個實例來恢復故障實例的計時器
內存復制配置
為了配置集群內存復制,必須執行三個步驟:
創建一個管理域。在創建域之後,在機器上創建它的節點代理,然後創建一個集群管理配置。這個配置設置復制的默認配置,啟用GMS並將persistence-type 屬性設置為replicated。
創建一個集群和它的實例(見本文後面的說明)。
部署web應用程序並將availability-enabled 屬性設置為true。
這些步驟可以用GUI或CLI來完成。
可能還需要做一些調整。例如,集群管理配置的默認堆大小是512 MB。對於企業部署,這個值應該增加到1 GB或更大。這很容易通過DAS完成,只需用以下標記設置JVM選項:
<jvm-options>-Xmx1024m</jvm-options>
<jvm-options>-Xms1024m</jvm-options>
還要確保在web應用程序的web.xml文件中添加<distributable />標記。這個標記表示這個應用程序支持集群。
要求插入<distributable />標記,這提醒您先在集群環境中對應用程序進行測試,然後才能將它部署到集群中。一些應用程序在部署到單一實例時工作得很好,但是在部署到集群時就會失敗。例如,在將一個應用程序成功地部署在集群中之前,屬於應用程序的HTTP會話的任何對象(比如有狀態會話bean)都必須是可序列化的,這樣才能跨網絡保留它們的狀態。當部署到單一服務器實例時,不可序列化的對象可能會正常工作,但是在集群環境中就會失敗。應該檢查您的會話數據的內容,確保它在分布式環境中可以正常工作。
內存復制實現
在GlassFish version 2應用服務器中,內存復制特性基於JXTA技術的傳輸和消息傳遞功能。
JXTA技術是許多人熟悉的對等技術。它定義為一組基於XML的協議,這些協議讓連接到網絡的設備可以交換消息並進行協作,而不會受到網絡拓撲的限制。在開發GlassFish version 2應用服務器時,改進了JXTA技術來處理內存復制的容量和吞吐量需求。為了提高可伸縮性和性能,內存復制特性的開發人員利用了 Grizzly項目 提供的協作功能,這個項目幫助開發人員用 Java New I/O API (NIO)構建可伸縮的健壯的服務器。
JXTA技術中的組成員關系抽象映射到GlassFish應用服務器集群和實例模型:JXTA組映射到GlassFish集群,JXTA對等體映射到GlassFish服務器實例。GMS是用於處理集群中的運行時事件的通知事件模型,它使用這些組成員關系抽象並提供內存復制等消費組件。
在開發GlassFish version 2應用服務器時,集群拓撲結構被限制在單一子網中。未來的計劃包括通過JXTA支持地理上分散的集群拓撲結構。
最後,JXTA技術的API非常簡單,這使GlassFish集群的配置非常簡單。
應用服務器安裝
安裝GlassFish應用服務器的步驟如下:
輸入以下命令:
java -jar filename.jar
例如:
java -jar glassfish-installer-v2-b58g.jar
接受許可協議。在接受許可協議之後,文件釋放到GlassFish安裝目錄(默認名稱為glassfish)中。
現在需要配置GlassFish應用服務器。
集群配置
安裝目錄包含兩個ant構建腳本,可以用它們創建默認域。這兩個腳本是setup.xml和setup-cluster.xml。
setup.xml腳本創建開發人員配置;setup-cluster.xml腳本創建集群配置。可以通過Sun Java System Application Server Admin Console將開發人員配置轉換為集群配置。
用集群配置創建默認域的步驟如下:
在GlassFish安裝目錄中輸入以下命令:
lib/ant/bin/ant -f setup-cluster.xml
配置腳本將存檔文件釋放,並創建domains子目錄和一個啟用集群的名為domain1的域。
GlassFish的配置現在完成了。
域檢查
可以通過CLI(asadmin命令)或GUI(Sun Java System Application Server Admin Console)了解和管理域。
從命令行界面檢查域
配置步驟在安裝目錄中創建了一個domains子目錄。這個目錄存儲所有GlassFish域。
可以從CLI用asadmin命令與域進行交互,這個命令在安裝目錄下的bin子目錄中。可以按照批處理模式或交互模式使用asadmin命令。
例如,可以用以下命令列出所有域及其狀態:
bin/asadmin list-domains
如果還沒有啟動domain1,那麼以上命令會產生以下輸出:
domain1 not running
輸入以下命令來啟動domain1:
bin/asadmin start-domain domain1
如果只有一個域存在,參數domain1就是可選的。這個命令啟動domain1並提供各種信息,包括日志文件的位置、服務器的版本、域名、可用的web上下文、部署的應用程序、使用的端口等等。
用Sun Java System Application Server Admin Console檢查域
可以使用Sun Java System Application Server Admin Console替代asadmin命令來控制應用服務器。下一節描述如何啟動這個控制台。
Admin Console簡化了從.war或.ear文件或JBI(Java Business Integration)服務配件部署應用程序的過程。在這個控制台上,可以監視資源的使用情況、搜索日志文件、啟動和停止服務器、訪問聯機幫助並執行許多其他管理和服務器管理功能。
為現有域啟用集群支持
可以在現有的域中添加集群支持。如果不修改配置的話,使用開發人員配置的域就不支持集群。在GlassFish安裝目錄中,使用以下命令創建一個開發人員配置域:
lib/ant/bin/ant -f setup.xml
在開發人員配置域中啟用集群支持的步驟如下:
在GlassFish安裝目錄中輸入以下命令,啟動要重新配置的域:
bin/asadmin start-domain domain_name
例如:
bin/asadmin start-domain domain1
這個命令在域中啟動GlassFish應用服務器,並在命令shell窗口中提供信息。最後一行信息描述域的功能;當前情況下,這一行是:
Domain does not support application server clusters and other standalone instances.
將web浏覽器指向以下URL,啟動Administration Console:
http://hostname:port
默認端口是4848。例如:
http://kindness.sun.com:4848
如果Administration Console在安裝應用服務器的機器上運行,那麼將主機名指定為localhost。在Windows上,從Start菜單啟動Application Server Administration Console。
默認的登錄信息是
用戶名:admin
密碼:adminadmin
在窗口左邊的Common Tasks樹中,選擇Application Server。在窗口右邊,選擇General選項卡。
單擊Add Cluster Support按鈕,如下圖所示。
圖10. 添加集群支持
這時顯示一個確認頁面,它指出修改集群支持會有哪些後果。要考慮以下情況:
修改域的配置來支持集群。修改包括添加幾個系統屬性和模板配置。
啟用集群的服務器將支持集群服務器實例和單獨的服務器實例。
因為集群常常會增加對資源的需求,所以可能需要修改管理服務器的JVM設置,比如堆大小。
在啟用集群的域中的服務器上,當前部署的所有應用程序都可以繼續工作。
對集群支持的修改會在重新啟動域服務器和asadmin CLI之後生效。
在繼續進行配置之前,可能希望備份域的domain.xml文件,以防需要恢復配置的情況。
單擊OK為域啟用集群支持。這時打開一個頁面,提示您重新啟動這個域的服務器實例。
單擊Stop Instance按鈕。
如果asadmin命令在命令shell中運行,那麼在asadmin>提示下輸入quit退出這個命令。
輸入以下命令從CLI重新啟動域:
asadmin start-domain domain_name
例如:
asadmin start-domain domain1
如果為這個域成功地啟用了集群支持,那麼命令shell中的最後一行輸出如下:
Domain supports application server clusters and other standalone instances
HTTP負載平衡器插件
負載平衡器將工作負載分配給多個應用服務器實例,這可以增加系統的總吞吐量。盡管在將會話請求分派給服務器實例時,負載平衡器層不需要特殊信息,但是它需要維護可用節點的列表。如果一個節點沒有對請求做出預期的回復,負載平衡器就選擇另一個節點。
負載平衡器可以用軟件或硬件實現。關於硬件負載平衡器的實現細節,請參考硬件供應商提供的信息。
GlassFish version 2應用服務器可以使用一個HTTP負載平衡器插件。這個插件可以與Sun Java System Application Server 9.1以及Apache Web Server和Microsoft IIS配合工作。這個負載平衡器還能夠將請求從一個服務器實例故障轉移到另一個實例,這會提高可用性。
關於設置負載平衡器插件的更多信息,請參考Sun Java System Application Server 9.1 Admin Console提供的聯機幫助。還可以參考 Sun Java System Application Server 9.1 High Availability Administration Guide中的Chapter 5, Configuring HTTP Load Balancing。
結束語
GlassFish version 2應用服務器提供一個靈活的集群體系結構,這個體系結構由管理域、域管理服務器、服務器實例和物理機器組成。這個體系結構容易使用,提供了很強的管理控制能力,可以提高可用性和水平可伸縮性。
高可用性 - 多個服務器實例能夠共享狀態,減少單點故障,尤其是在與負載平衡方案結合使用的情況下。服務器會話狀態數據的內存復制可以減少服務器實例故障對用戶的干擾。
水平可伸縮性 - 隨著用戶負載的增加,可以輕松地添加和配置更多的機器、服務器實例和集群來處理增加的負載。GMS降低了維護高可用性集群的管理負擔。