集羣是指把不一樣的服務器集中在一塊兒,組成一個服務器集合,這個集合給客戶端提供一個虛擬的平臺,使客戶端在不知道服務器集合結構的狀況下能夠對這一服務器集合進行部署應用,獲取服務等操做。集羣是企業應用的主要特色,它能夠提供:html
不論是擴展本身的集羣的節點數,仍是配置負載均衡、容錯,集羣中各節點之間狀態必須保持一致,集羣中狀態保持一致須要藉助與緩存機制實現(JBoss使用JGroups,Infinispan咱們在後面的系列介紹)。以下圖爲一傳統企業應用集羣模式:
node
圖-1傳統企業應用集羣
linux
1. 客戶端瀏覽器發送請求git
2. 負載均衡器轉發請求到節點1github
3. 節點1處理業務時發生異常web
4. 負載均衡切換請求到節點2瀏覽器
5. 節點2完成業務請求返回結果給客戶端請求緩存
上述業務請求完成過程當中客戶端不知道服務器端節點1發生異常。業務可以完成的核心是兩個節點之間實時進行着狀態複製,而狀態複製須要藉助於緩存框架和產品(JBoss使用JGroups,Infinispan咱們在後面的系列介紹)。服務器
Apache httpd做爲負載均衡器和後臺中間件服務器構建構架高可用企業應用集羣是很是廣泛的一種方式,當前主要三大中間件JBoss,Weblogic,Websphere都支持Apache httpd做爲負載均衡器。JBoss作爲開源的產品是最被普遍使用的中間件,JBoss在被Red Hat公司收購後又推出企業版EAP(EnterpriseApplication Platform),從而使JBoss在許多核心業務領域被使用。好比印度鐵路系統底層爲JBoss; 2012倫敦奧運會系統底層是4臺JBoss的集羣等。以下咱們將使用JBoss和Apache httpd給出一個構建高可用企業應用集羣的解決方案。
網絡
本方案使用開源JBoss社區的產品搭建一個高可用企業集羣環境,負載均衡器位於集羣節點之上。經過本方案咱們能夠體會到企業應用的高可用性主要是由於集羣節點之間狀態保持同步,即會話複製(Session Replication),而如何進行會話複製則是本書主要論述的主題。咱們先給出本方案的架構圖:
圖-2 方案設計架構
如上,使用JBoss AS7作爲集羣節點,爲了簡單咱們只使用兩臺JBoss,即集羣中就有兩個節點。Apache httpd 和 mod_cluster 作負載均衡器,mod_cluster做爲Apache的插件模塊負責鏈接Apache和JBoss,根據負載均衡策略分發和請求給後臺JBoss,因此咱們能夠將Apache httpd 加mod_cluster做爲負載均衡器。
本方案會話複製是經過JBoss社區產品JGroups和第二代JBossCache產品Infinispan完成的,但本處咱們不對JGroups和Infinispan作任何探討,咱們將在後面的系列詳細討論JGroups和Infinispan。
另外,本方案是在開源Linux操做系統Fedora 15上進行,咱們列出本方案使用的硬件和軟件,三臺物理機器,內存4GB或以上,安裝Fedora 15後IP地址分別爲10.66.192.48,10.66.192.231,10.66.192.232,咱們分別對這三臺物理機器作相應的安裝以下:
接下來咱們將從方案配置,測試應用的安裝,及結果分析等方面展開討論此方案。
在 JBoss 社區mod_cluster頁面(http://www.jboss.org/mod_cluster)選擇下載(Downloads),選定相應的版本(1-2-0-Final),彈出頁面會列出因此相關的 Java 模塊(主要用來與JBoss AS 6以及以前的版本完成集羣配置)、編譯完成的Apachehttpd、Apache httpd端動態模塊包。根據您的平臺選擇相關包進行下載咱們會獲得以下文件:
解壓mod_cluster-1.2.0.Final-bin.tar.gz咱們會獲得一些用於JBoss AS 6及以前版本的Java組件和測試例子等。
解壓mod-cluster-1.0.0-linux2-x86-ssl.tar.gz咱們會獲得一個安裝配置完成的httpd位於opt/jboss目錄下。這裏咱們不使用此安裝,咱們使用從操做系統層面以安裝包方式安裝,以下文所示。
解壓 mod_cluster-1.2.0.Final-linux2-x86-so.tar.gz ,咱們會獲得以下包:一樣以下文所示咱們須要將這些動態包拷貝到Apache httpd 的modules 目錄下,這些包用來維護、管理Apache httpd與後臺JBoss之間的鏈接,通訊。
請參照系列一 Apache httpd 安裝(http://blog.csdn.net/kylinsoong/article/details/12291173)
編輯httpd/conf/httpd.conf,讓httpd監聽在10.66.192.48:80上:
Listen 10.66.192.48:80拷貝mod_cluster全部.so文件(mod_advertise.so ,mod_manager.so ,mod_proxy_cluster.so,mod_slotmem.so)到httpd/modules目錄:
cp *.so /etc/httpd/modules編輯httpd/conf/httpd.conf,註釋掉mod_proxy_balancer模塊,覺得此模塊與mod_cluster相關模塊不兼容:
# LoadModule proxy_balancer_module modules/mod_proxy_balancer.so在httpd/conf.d目錄下建立JBoss_HTTP.conf文件,將以下內容添加到此文件:
# add mod_cluster reference module LoadModule slotmem_module modules/mod_slotmem.so LoadModule manager_module modules/mod_manager.so LoadModule proxy_cluster_module modules/mod_proxy_cluster.so LoadModule advertise_module modules/mod_advertise.so Listen 10.66.192.48:6666 <VirtualHost 10.66.192.48:6666> <Directory /> Order deny,allow Allow from all </Directory> <Location /mod_cluster-manager> SetHandler mod_cluster-manager Order deny,allow Allow from all </Location> KeepAliveTimeout 60 MaxKeepAliveRequests 0 AdvertiseFrequency 5 ManagerBalancerName kylincluster ServerAdvertise Off EnableMCPMReceive On </VirtualHost>
咱們能夠經過以下三種方式添加proxy-list,balancer完成JBoss端集羣配置:
1. 修改配置文件
編輯/standalone/configuration/standalone-ha.xml文件,找到urn:jboss:domain:modcluster部分,修改mod-cluster-config的屬性以下:
<mod-cluster-config advertise-socket="modcluster" proxy-list="10.66.192.48:6666" balancer="kylinBalancer" sticky-session="true" connector="ajp">保存修改文件即完成配置。
2. 經過Web管理界面
以standalone-ha.xml模式(./standalone.sh -c standalone-ha.xml)啓動JBoss後登陸管理界面(http://localhost:9990/console),選擇Profile,Web,mod_cluster,在彈出界面點擊相關按鈕,編輯balancer值爲kylinBalancer,proxy-list值爲10.66.192.48:6666,sticky-session值爲true,點擊保存按鈕即完成配置。
3. 經過命令行管理窗口
以standalone-ha.xml模式(./standalone.sh -c standalone-ha.xml)啓動JBoss後進入到命令行界面,依次執行以下命令:
/subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=balancer,value=kylinBalancer) /subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=sticky-session,value=true) /subsystem=modcluster/mod-cluster-config=configuration/:write-attribute(name=proxy-list,value=10.66.192.48:6666)
說明:以上三個步驟中說起的proxy-list,balancer的值須要與Apache httpd端配置想對應,咱們應該依次對兩個節點進行配置
Linux操做系統下使用以下命令完成啓動Apache httpd:
service httpd start2. 使用以下命令依次啓動JBoss兩個節點
./standalone.sh -c standalone-ha.xml -b 10.66.192.231 -bmanagement 10.66.192.231 -u 239.255.100.100 -Djboss.node.name=node1 -Djboss.mod_cluster.jvmRoute=node1
./standalone.sh -c standalone-ha.xml -b 10.66.192.232 -bmanagement 10.66.192.232 -u 239.255.100.100 -Djboss.node.name=node2 -Djboss.mod_cluster.jvmRoute=node2
啓動完成分別登陸以下界面測試:
本部分包括部署測試應用,容錯性和高可用性測試,結果分析三個方面去說明。
使用git clone 咱們本系列所需的測試代碼(參照系列一github客戶端安裝部分),clone完成後進入系列二目錄,也是咱們這裏所使用的測試工程,具體:
cd csdn/2/在該目錄下執行Maven( Maven安裝參照系列一Maven安裝部分)編譯 系列二工程:
mvn clean install編譯完成後會生成webcluster-session-replication.war,路徑爲csdn/2/target/webcluster-session-replication.war, 分別部署webcluster-session-replication.war到兩個JBoss節點上(圖-2方案設計架構中IP地址爲10.66.192.231和10.66.192.232機器)。檢查兩個節點JBoss Console端的日誌輸出,若是沒有異常顯示則證實測試應用部署完成。
部署成功後咱們在Apache httpd所在的機器(IP地址爲10.66.192.48)訪問應用,具體使用http://10.66.192.48/sessionReplication訪問測試應用,在打開的頁面中點擊藍色添加按鈕添加內容三次,結果顯示以下圖所示:
圖-3 應用測試截圖
1. 負載均衡器將請求分發給了節點一
如上圖所示,處理業務邏輯的服務器是10.66.192.231/node1機器,也就是說負載均衡器(Apache httpd 和 mod_cluster) 分發請求到10.66.192.231 節點1 JBoss。
2. 測試集羣間的狀態複製
因爲節點1和節點2進行着狀態複製,因此添加在節點1上的三條信息也複製到節點2,因此若是咱們接下來經過8080端口直接訪問節點2(http://10.66.192.232:8080/sessionReplication)會看到以前經過Apache端(http://10.66.192.48/sessionReplication)添加的內容已經存在於節點2上。
3. 容錯性高可用性測試
如上負載均衡器(10.66.192.48)將請求分發給節點1(10.66.192.231),接下來咱們關閉節點1JBoss,咱們會發現請求(http://10.66.192.48/sessionReplication)會自動切換到節點2(10.66.192.232),上述自動切換完成過程當中客戶端不知道服務器端節點1發生異常,這體現了集羣的容錯性高可用性測試。
咱們經過以下圖中所示的4步解釋說明Apache httpd和JBoss構架高可用集羣環境中爲何負載均衡器(10.66.192.48)可以將請求分發到工做集羣節點(10.66.192.231和10.66.192.232)上,咱們基於圖-4:
圖-4負載均衡器分發請求到集羣節點
第一步:負載均衡器將本身廣播到多播組,告訴JBoss集羣節點"I'm here"
第二步:JBoss集羣節點經過多播組發現負責均衡器,並加入集羣
第三步:使用MCPM協議獲取集羣節點信息,鏈接或斷開節點
第四步:使用ajp/http/https轉發請求到集羣節點
分析如上結果,節點1和節點2之間進行會話狀態同步是經過JBoss緩存產品Infinispan和JGroups完成的,Infinispan和JGroups是JBoss社區優秀產品,我會在後面的系列作詳細介紹。JBoss節點間會話複製大致架構以下圖所示:
圖-5 Web會話複製過程
JGroups是一個可靠多波通訊工具,藉助於網絡多波通訊進行狀態複製,Infinispan則基於JGroups之上的分佈式緩存。
JBoss集羣進行狀態複製是由於咱們作了以下的配置:
1. JBoss端Infinispan相關配置以下:
<subsystem xmlns="urn:jboss:domain:infinispan:1.2"> <cache-container name="web" default-cache="repl-sync"> <transport stack="udp"/> <replicated-cache name="repl-async" mode="ASYNC"/> <replicated-cache name="repl-sync" mode="SYNC"/> <distributed-cache name="dist-async" owners="2" mode="ASYNC"/> <distributed-cache name="dist-sync" owners="2" mode="SYNC"/> </cache-container> </subsystem>
<subsystem xmlns="urn:jboss:domain:jgroups:1.1" default-stack="udp"> <stack name="udp"> <transport type="UDP" socket-binding="jgroups-udp"/> <protocol type="PING"/> <protocol type="FD_SOCK" socket-binding="jgroups-udp-fd"/> <protocol type="pbcast.NAKACK"/> <protocol type="UNICAST2"/> <protocol type="pbcast.STABLE"/> <protocol type="pbcast.GMS"/> <protocol type="FRAG2"/> </stack> <stack name="tcp"> <transport type="TCP" socket-binding="jgroups-tcp"/> <protocol type="MPING" socket-binding="jgroups-mping"/> ... </stack> </subsystem>
3. webcluster-session-replication.war/WEB-INF/web.xml端配置:
<distributable/>
<replication-config> <cache-name>web.repl-async</cache-name> </replication-config>