clustering 經典範文學習

轉自:http://blog.csdn.net/calvinxiu/article/details/1602891



      
 構造Cluster是架構師們實現ScalabilityHigh Availability 的最直接用藥。所以大家很多都會無意中使用Cluster的思想去設計自己的服務器。其實Java EE裏的Clustering已經做得很熟很爛,大家如果爛熟各家vendor對Web,EJB,JNDI,JMS,WebService....的Cluster實現,再思考自己的爛攤子時,思路便快捷清晰,少很多與同僚們的無謂爭論。

     JavaEE Cluster的經典範文是Sun的王昱寫於2005年的Uncover the hood of J2EE Clustering Preface,更可貴的是dev2dev上的JadeYuan兄弟將它高質的翻成了中文。 

 一、所謂集羣  

          目的就是以負載均衡(Load Balance)與失敗轉移(Failover) 實現可擴展性(Scalability)和高可靠性(High Availability),主要實現的功能: 

Load Balance 算法主要有輪循、權重(根據服務器硬件配置的不同)和隨機三種,但更酷的做法是基於負載(直接查探或者服務器主動報告它們的負載)。

Health Check心跳系統與發現協議。Server一般會主動定期多播報告自己狀態,也會Ping對方來問候平安。比如Weblogic每10秒會向全世界發送一次心跳,如果有30秒沒有收到某個服務器的心跳了(考慮到多播可能會丟失數據包)就可視對方爲陣亡。

Session Replication 因爲服務器會記錄與特定用戶的會話信息,Balancer應該把同一用戶的請求定位到同一臺服務器上。如果該服務器失效,就把該用戶和會話信息轉移到新服務器上。

除了Scalability 與High Availability,一個集羣還應該對已有代碼影響最小,對性能影響最小,配置與部署簡單,以及運行時可監控。

 二、Web層羣集 

    Balancer無非Apache/IIS插件,balance Servlet,硬件四層交換機三類,而討論的重點在Session 信息的Replication 實現上,簡單的分有全部服務器冗餘備份,三三兩兩互爲冗餘備份,中央備份服務器三種模式。

              1.多服務器全冗餘備份
              Tomcat的最爲粗糙,最沒有擴展性的做法,不提。Sun的怪怪的replacate的內存數據庫法HADB可能也屬於這種範疇。

              2.三三兩兩互爲冗餘備份
              Weblogic, Jboss and WebSphere 的做法,好主流。A會有B的數據,B會有C的數據,C會有B的數據,如果A出錯,就會由C接替A的工作。這種做法的弊端是:
              1.要控制failover到備份服務器,Balancer的實現複雜度高。
              2.如果A出錯,C就要瞬時承載A、C的操作,很可能將它壓垮,針對這點,Weblogic的做法是針對每個session而不是每個Server選擇備份服務器,把主備服務器A、B的名字寫在用戶Cookie裏,如果A失效後,Balancer會根據cookie將用戶轉到服務器B。
              3.相對沒有cluster的方案,需要花額外的時間和內存。

              文中沒講的Geronimo使用的WADI,應該也屬於這種類型,不過更爲靈活,詳見Geronimo 叛逆者: 加入集羣功能第1部分 和 第2部分。

              3. 中央備份服務器
              N+1模式,一箇中央Server存放所有的Session,如果一臺Server死了,接管的Server就從中央服務器restore相關數據。可以用數據庫(很多應用服務器都支持的最簡單,但最慢的模式),也可以採用內存。這種方式好處是cluster服務器上不需要冗餘內存,可以failover到任意服務器,cluster服務器全死了中央服務器都不死。壞處就是如果中央服務器死了...如果中央服務器的內存不夠了.....另外,多了個restore的步驟。

        使用內存備份session時,Tomcat/JBoss使用的JavaGroups 是一個很好的工具,它的" Group membership protocols" and "message multicast"特性都非常有用。

        另外,無論使用內存還是數據庫,都需要串行化Java對象,性能損耗厲害,所以JRun 就採用了Jini架構 ,而Tangosol Coherenc ,Terracotta這些Data Grid方案都提出了自己的session備份做法,整天顯示着比傳統方案快多少多少。Data Grid分佈式緩存本身就是很Enterprise的功能,下篇blog再詳述。 

三、EJB集羣

從stub 調用實際EJB對象時,有三種方法實現負載均衡和fail over:

  1. Smart Stub.在stub內維護有效列表,實現負載均衡邏輯,進行實效檢測,BEA Weblogic and JBoss 採用。
  2. IIOP Runtime Library ,Sun的JES 算法,把算法從客戶端的stub移到客戶端的IIOP Runtime
  3. Interceptor Proxy,IBM做法,把算法移到了服務端,Location Service Daemon (LSD)。

在JNDI查找EJBHome,EJBHome Stub查找生成EJB實例,調用EJB方法三種時候都可以實現負載均衡,對statefull,stateless,entity bean,又有不同的做法。

EJB需要具有冪等性(在部署描述符中聲明)才能failover。

四、其他集羣

JMS集羣,可以有多個broker組成集羣(JBoss,如果要持久化Message,就要把原來嵌入式的數據庫改爲共享模式),activeMQ還支持多個消費者組成集羣,但每個消費者負責同一類的任務,比如訂單隊列的處理,Server A只處理圖書類的訂單,或只處理《Programming Ruby 2nd》的訂單。

數據庫集羣有Oracle的RAC,但JDBC本身的failover能力很低,一旦connection 中斷,resultset等對象都會失效,Weblogic的連接池會嘗試重連。

五、走的更遠

   Weblogic9/10的廣域網羣集和服務器遷移(有些服務在羣集中只能有一個實例在運行,如果該實例失效,遷移到下一個實例)功能。

    如果只要單純的load balance,不要fail over的話,使用純硬件如F5已經足夠,不需要在軟件上做任何事情。

   羣集有兩種模式,一種是隻在入口的Web層進行負載均衡,一種是Web層和對象層(EJB)分別進行負載均衡。

六、Cluster的神話

1.Failover可徹底避免錯誤
   JBoss的文檔用了整整一章來警告你,真的需要http session複製嗎?沒有http session可以使效率提高很多,而有了的話,並不能避免所有錯誤。失敗轉移只能在兩次調用間產生作用,在調用時產生的錯誤是無法恢復的,除非這是個冪等操作(如單純的get(),而不是put(),無論如何重複操作結果都是一樣的),否則,如果A上承載100用戶,失敗時有20個用戶正在進行處理,則只有80個用戶能逃出生天平安轉移到B。

2.小心編寫可集羣的程序

1.http session要放能serilaze的對象,對象不要太大,變更時要顯式的setAttribute().

2. 注意Cache的使用。如果每個JVM獨立使用Cache,會否不一致,如果進行同步,注意開銷。

3.不能使用靜態變量,如在線用戶數,要搞成分佈式的 Cache。

4.外部資源如文件系統(一臺機器上沒有另外一臺機器的文件),存成DB或者使用SAN

5.特別服務:如timer服務,基於事件的服務


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章