table

          J2EE集群原理 II

          J2EE集群原理 II

          二. JNDI集群
          Jndi集群對于EJB也是非常重要的,因為幾乎所有的EJB都是從JNDI調(diào)用開始的
          I. 共享全局JNDI樹
          Weblogic和JBOSS都使用一個全局的、共享的、分布在整個集群系統(tǒng)的JNDI樹,對象被綁定到全局上下文,使用ip多播方式拷貝JNDI數(shù)據(jù)
          aaaaa

          圖十四:全局共享JNDI
          集群中的每個節(jié)點都有自己的命名服務(wù)器,并且自動保存其他所有節(jié)點的JNDI數(shù)據(jù),因此這種結(jié)構(gòu)具有高度可靠性
          實際中,集群JNDI樹主要有兩個用途:一是用于部署,你只需要將某個EJB部署到一臺服務(wù)器上,系統(tǒng)會自動將其拷貝到其他節(jié)點。二是在運行中你可以用JNDI存取自己的對象,這些自定義對象同樣會被自動拷貝到其他節(jié)點。
          II.獨立的JNDI樹
          Sun JES, IBM Websphere和其他廠商使用的是獨立的JNDI樹,各個節(jié)點擁有自己獨立的JNDI,而不會關(guān)心其他節(jié)點的JNDI。但這并不意味著它們不能實現(xiàn)集群,關(guān)鍵是每臺服務(wù)器上的配置要相同,應(yīng)用也要相同,這樣的話通過代理agent就能實現(xiàn)高性能的集群了

          Sun JES 和 IBM Websphere都在每個節(jié)點處安裝了一個agent,由console負(fù)責(zé)協(xié)調(diào)各個agent
          但這種方式不支持動態(tài)綁定運行時生成的對象,設(shè)計者的理由是:JNDI本身就是作為管理外部資源的中間層,運行時對象綁定不在JNDI的職責(zé)范圍內(nèi),如果真的有這種需要,可以使用LDAP或者具有HA功能的數(shù)據(jù)庫。Sun和IBM都有自己的LDAP實現(xiàn)

          III. 中央型JNDI樹
          少數(shù)廠商采用中央型的JNDI,所有節(jié)點都去一個某個指定的JNDI服務(wù)器上獲取資源,當(dāng)然這對于客戶端來說是透明的。不過這種方式會大大增加安裝和管理的復(fù)雜性,因此被大部分廠商放棄

          怎樣開始連接JNDI呢
          使用JNDI,你必須知道提供JNDI服務(wù)的域名或IP以及端口,在全局和獨立型JNDI樹中,都存在著多個JNDI服務(wù)器,客戶端要連接哪一個呢,負(fù)載均衡和失敗恢復(fù)又是如何實現(xiàn)的呢?

          技術(shù)上來說,可以在客戶端和JNDI服務(wù)器之間放一個硬件或軟件實現(xiàn)的負(fù)載均衡器,來實現(xiàn)上述要求,不過大部分廠商都有更加簡單的方法:

          * SUN JES 和JBOSS 能夠令“java.naming.provider.url”這一JNDI屬性支持用逗號分隔多個地址,例如,“java.naming.provider.url=server1:1100,server2:1100,server3:1100,server4:1100”,客戶端會逐個搜索,直到找到一個可用的為止

          * JBOSS還支持自動找尋功能,即令“java.naming.provider.url”屬性為空,客戶端會自動以網(wǎng)絡(luò)多播的方式尋找一個JNDI服務(wù)器作為查詢的起始點


          三. EJB集群原理
          EJB衍生自分布式計算技術(shù),服務(wù)器組件或富客戶端都能夠以標(biāo)準(zhǔn)協(xié)議(RMI/IIOP)調(diào)用遠程的EJB,并且RMI/IIOP技術(shù)能夠屏蔽底層網(wǎng)絡(luò),使得EJB的調(diào)用對客戶透明化


          圖:EJB調(diào)用原理


          如圖,客戶端不是直接和EJB打交道,而是通過stub來代理。Stub負(fù)責(zé)利用RMI找到遠程的EJB并進行調(diào)用。EJB的調(diào)用過程分為下面三步(EJB2.0)

          1.從JNDI中查找EJBHOME stub
          2.利用home stub創(chuàng)建一個EJB Object stub
          3.利用EJB Object stub調(diào)用EJB的方法

          在JNDI查找時,可以利用上文說到的方法進行負(fù)載均衡;各廠商也會有自己專門的技術(shù)對stub的使用進行負(fù)載均衡,一般有以下三種方式:

          Smart stub

          我們知道,stub可以通過JNDI來獲得和創(chuàng)建,甚至可以直接下載相應(yīng)的class文件來在運行時動態(tài)生成,而無須在客戶端本地的classpath中聲明


          圖十七:smart stub


          如圖十七,Weblogic 和JBOSS通過在stub的代碼中嵌入特殊的代碼來實現(xiàn)集群,這個stub的確相當(dāng)smart,它包含了所有能夠訪問的集群服務(wù)器節(jié)點、內(nèi)置了專門的集群算法來決定把請求發(fā)給何處,甚至當(dāng)集群的拓?fù)溆凶儠r(比如增加了節(jié)點),能動態(tài)改變自身來適應(yīng)新的結(jié)構(gòu),無須手工干預(yù)
          Smart stub有以下幾個好處:

          1.節(jié)省大量服務(wù)器資源
          2.由于負(fù)載均衡是由客戶端處理,因此可以防止在服務(wù)器端放置負(fù)載均衡器而可能導(dǎo)致的單點失敗
          3.Stub可以動態(tài)下載安裝,意味著無須手工維護

          IIOP Runtime Library

          Sun JES采用另一種方法,它直接修改客戶端的IIOP運行時庫

          圖十八:IIOP Runtime

          如圖十八,sun直接把負(fù)載均衡邏輯轉(zhuǎn)移到了IIOP庫中,從而使stub能夠保持“小而輕”,同時由于IIOP是底層庫,能夠更加有效地獲取和使用JVM提供的資源。但正是由于底層庫有所不同,使得JES與其他J2EE服務(wù)器打交道時可能會出現(xiàn)一些問題

          Interceptor Proxy

          IBM Websphere使用Location Service Daemon (LSD)作為一個攔截器代理來實現(xiàn)EJB集群

          Figure 19: Interceptor Proxy

          使用這種機制,stub中包含至LSD的路由信息,而不是直接去找服務(wù)器節(jié)點,這樣LSD就能獲得所有請求并進行負(fù)載均衡了,不過這樣會大大增加管理和維護的成本

          EJB的集群支持
          調(diào)用EJB方法的過程中我們要和兩個stub打交道,一個是home stub,另一個是object stub,因此可以在兩個層面上實現(xiàn)負(fù)載均衡和失敗恢復(fù)

          1.EJBHOME STUB的集群實現(xiàn)
          由于EJBHOME STUB本身不包括任何客戶端信息,無論從哪個服務(wù)器上獲得的EJBHOME STUB都是一樣的,因此當(dāng)客戶端調(diào)用EJBHOME STUB的create等方法時,就能利用一些負(fù)載均衡的算法選擇合適的服務(wù)器節(jié)點
          2.EJBOBJECT STUB的集群實現(xiàn)

          EJBOBJECT STUB包含業(yè)務(wù)接口,而且其本身也能夠含有集群節(jié)點的信息,但也不是所有的方法調(diào)用都能夠進行負(fù)載均衡式的路由,得看EJB的類型是什么
          無狀態(tài)會話bean最容易實現(xiàn)負(fù)載均衡了,因為它本身不包含特定的客戶信息

          有狀態(tài)會話bean略有不同,因為它本身包含客戶端的會話信息,因此有狀態(tài)bean的集群實現(xiàn)本質(zhì)上和HTTP session 無異,一般情況下客戶端的stub都是一直與某個節(jié)點上的EJB組件打交道的,除非中途出問題了才會將請求轉(zhuǎn)發(fā)到備用的節(jié)點上

          實體bean本質(zhì)上也是無狀態(tài)的。表面上看可以采用和無狀態(tài)會話bean一樣的方式集群,但實際上很少廠商會對實體bean做集群。因為實體bean一般都是被其他會話bean調(diào)用的,因此通常都使用本地接口通訊,實在沒有集群的必要

          四.JMS和數(shù)據(jù)庫連接的集群

          目前一些數(shù)據(jù)庫產(chǎn)品已經(jīng)可以集群了,你可以部署成多份,每個節(jié)點之間可以同步。但是JDBC本質(zhì)上是有狀態(tài)連接,和底層的socket緊密綁定。當(dāng)某個JDBC連接突然中斷了,與之相關(guān)的對象也就費了,因此很難對JDBC集群。Weblogic使用一種JDBC multipool,可以在JDBC斷開情況下,方便地進行重新連接

          JMS的負(fù)載均衡和失敗恢復(fù)只在JMS broker上有實現(xiàn),很少有廠商在JMS destination 的消息上實現(xiàn)了負(fù)載均衡

          五.關(guān)于J2EE集群的神話
          失敗恢復(fù)能夠防止所有錯誤嗎?——錯!
          JBOSS的文檔花了整整一章的內(nèi)容來提醒你:“你真的需要HTTP SESSION復(fù)制嗎”,有時候不用失敗恢復(fù)也能以經(jīng)濟的方式獲得高可靠性。更何況,失敗恢復(fù)并沒有你想象中的那么可靠

          你也許認(rèn)為失敗恢復(fù)能夠在節(jié)點宕機時保護你的session數(shù)據(jù),但你得清楚,這種保障是有代價的。

          回想一下作者在定義“失敗恢復(fù)”時,前提條件是“在兩個方法調(diào)用之間”!也就是說只有在第一個方法成功返回之后、第二個方法調(diào)用開始之前,失敗恢復(fù)才能起作用

          假設(shè)某個方法處理到一半時服務(wù)器不幸掛掉了,客戶端一般只能收到錯誤消息。除非你這個方法恰好是“idempotent”的(即多次調(diào)用的結(jié)果都能保持一致,不會對環(huán)境造成任何改變,比如getter方法),那么有些聰明的負(fù)載均衡器會嘗試找其他節(jié)點去調(diào)用這個方法

          所以說“idempotent”這個概念非常重要,因為客戶端壓根不知道是在什么地方失敗的,而如果這個方法不是idempotent,那么系統(tǒng)就可能處于一種不一致的狀態(tài),很危險

          你也許認(rèn)為事務(wù)性的方法就是idempotent的,畢竟事務(wù)可以回滾。但其實事務(wù)遠遠不能涵蓋整個遠程調(diào)用的范圍,比如服務(wù)器成功執(zhí)行某事務(wù)性方法后,返回結(jié)果的過程中網(wǎng)絡(luò)崩潰了呢?
          在比較嚴(yán)格的系統(tǒng)設(shè)計中,你根本不能令所有方法都idempotent,你能做的就是利用failover,盡可能減少錯誤而不是徹底杜絕錯誤。以某個網(wǎng)上商城為例:每臺服務(wù)器都同時處理100個用戶請求,當(dāng)某臺服務(wù)器崩潰時,如果沒有失敗恢復(fù),那么你會得罪一百個用戶;而如果有失敗恢復(fù),可能只有不到20個用戶會發(fā)飆。你自己要權(quán)衡:
                  1.是得罪一百個客戶還是得罪20個客戶?
                  2.有沒有失敗恢復(fù)的服務(wù)器的價格差別

          獨立的應(yīng)用程序可以無縫地遷移到分布式平臺上?——錯!
          這只是某些廠商的廣告而已,不可輕信。如果是大型系統(tǒng),那么設(shè)計之初就應(yīng)該全盤考慮集群可能造成的影響.

          HTTP  SESSION
          正如前文所述,HTTP SESSION的集群會受到你使用的服務(wù)器的諸多限制。首先是可序列化的要求,在很多MVC架構(gòu)中,session被用來存儲一些不可序列化的對象(比如servlet context);其次,序列化、特別是數(shù)據(jù)庫方式的序列化非常耗費資源,因此要集群就盡量不要用session存儲大對象。如果是內(nèi)存拷貝的方式,那么就要考慮內(nèi)存的限制和交叉引用的問題(交叉引用請參考前文);最后,你在集群環(huán)境下改變session的屬性時,必須使用“setAttribute”方法,而在單機環(huán)境下卻沒這個限制。這么做的主要原因是讓你的應(yīng)用服務(wù)器能夠檢測到屬性改變,及時地備份已修改的屬性

          緩存
          大部分流行的應(yīng)用服務(wù)器都會使用緩存來提升性能,但緩存一般都是為單機環(huán)境設(shè)計的。集群環(huán)境下如果使用緩存,那么緩存之間的拷貝花費的性能將比緩存帶來的好處還多,適得其反

          靜態(tài)變量
          有一種很流行的J2EE設(shè)計模式“singleton(單體)”,是使用靜態(tài)變量的,這在單機環(huán)境下適用,但到了集群就不行了,道理很簡單,每個JVM都有自己的靜態(tài)對象,“單體”也就失去意義了。比如要統(tǒng)計在線用戶數(shù)時,經(jīng)常用一個靜態(tài)變量來存儲,但是在集群環(huán)境下這種方法顯然失去作用。要使用靜態(tài)對象,最好把它放到一個數(shù)據(jù)庫中,才能實現(xiàn)全局的“單體”

          外部資源
          盡管J2EE規(guī)范并不推薦,但外部IO操作還是有用的,比如用來存放用戶上傳的文件。在集群中,服務(wù)器是不能通過另一臺服務(wù)器把本地文件直接存放到別的機器上的,那么還是要依靠數(shù)據(jù)庫來統(tǒng)一存放文件,或者你可以使用SAN這種集中式文件倉庫

          專有服務(wù)
          有些專有服務(wù)是只限于單機環(huán)境的,比如定時器服務(wù)(timer);再比如某些事件觸發(fā)類型的服務(wù),如初始化服務(wù),郵件提醒服務(wù)也屬于此列。這些服務(wù)一般針對一個特定條件只發(fā)生一次,拿去集群沒什么意義。JBOSS的“clustered singleton facility”就是用來保證所有服務(wù)器運行且只運行一次某種服務(wù)

          分布式系統(tǒng)比并列式系統(tǒng)更靈活?——未必

          盡管EJB生來就是為了分布式、解耦合,但很多框架認(rèn)為把EJB層和web層放在一起也未嘗不是好事,或許更好

          圖20:分布式架構(gòu)

          如圖20,負(fù)載均衡器先將請求分發(fā)到適當(dāng)服務(wù)器的web層,web層進一步判斷調(diào)用何處的EJB,這等于是做了兩次的負(fù)載均衡和失敗恢復(fù)。很多人認(rèn)為這種設(shè)計并不好:
                  1. 首先,第二次的轉(zhuǎn)發(fā)根本沒有必要,每個服務(wù)器都有自己的web和ejb層,比起只調(diào)用內(nèi)部的ejb,web層調(diào)用其他ejb層沒有任何的好處
                  2. 第二次的失敗恢復(fù)也是沒有必要的,大部分廠商都把web容器和ejb容器實現(xiàn)為在同一個jvm上跑,那樣一旦web容器掛了,ejb容器很難獨善其身
                  3. 損失性能,這個不必解釋了,大量的服務(wù)器之間的調(diào)用對性能肯定有影響。

          實際上,大部分廠商都讓web容器優(yōu)先選擇同一個服務(wù)器上的ejb容器,這種方式稱作“并列式”,是分布式的一種特例,如下圖

          圖21:并列式


          這樣引出一個有趣的問題:既然都放一塊了,為什么不直接用ejb的本地接口呢?雖然本地接口可以提高性能,但它卻把web和ejb緊耦合在一起了,負(fù)載均衡機制也就沒有辦法對其進行優(yōu)化,特別是當(dāng)你要變成分布式的時候

          此外很不幸的是,在集群環(huán)境下本地接口的使用經(jīng)常受到限制,因為有本地接口的ejb通常是不可序列化的。所以有些應(yīng)用服務(wù)器,比如sun JES,對本地接口的ejb做了特殊處理使其可以被序列化,從而保存到諸如session中去

          還有一個問題是,既然大部分情況下并列式的性能都比較好,那還要分布式干什么呢?其實在某些情況下還非得用分布式不可:
                  1. 除了web容器,富客戶端也要調(diào)用ejb組件
                  2. Web容器和ejb容器所處的安全級別不同,它們物流上也被放在不同的地方,中間加上一個防火墻
                  3.Ejb和web層的極度不對稱。指的是復(fù)雜度的不對稱,比如ejb層有大規(guī)模的運算,那就放在一臺高級的服務(wù)器上,而web容器只需放在一臺pc上即可.

          六.結(jié)論
          集群與單機環(huán)境是有很大不同的,各廠商的集群實現(xiàn)也不同。最好在項目開始就考慮到集群,使得你的系統(tǒng)更有擴展性,根據(jù)自身的需求選擇最合適的應(yīng)用服務(wù)器,并且選購第三方軟件時也要考慮到對集群的支持。最后,合適的架構(gòu)可以讓你受益于集群而不是讓集群成為你的噩夢


          關(guān)于原作者

          引用
          Wang Yu presently works for GPE group of Sun Microsystems as a Java technology engineer and technology architecture consultant. His duties include supporting local ISVs, evangelizing and consulting on important Java technologies such as J2EE, EJB, JSP/Servlet, JMS, Web services technologies. He can be reached at yu.wang@sun.com.

          posted on 2010-01-12 17:52 小卓 閱讀(387) 評論(0)  編輯  收藏 所屬分類: 服務(wù)器架構(gòu)


          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 普安县| 克东县| 乌兰察布市| 凌云县| 曲周县| 民乐县| 定结县| 乐业县| 庆城县| 乐安县| 兴仁县| 中阳县| 进贤县| 当阳市| 麻栗坡县| 巩义市| 尖扎县| 达拉特旗| 英吉沙县| 满城县| 莫力| 行唐县| 明光市| 海兴县| 英吉沙县| 长寿区| 大邑县| 电白县| 武汉市| 洮南市| 临漳县| 泰安市| 乐亭县| 黑水县| 盘山县| 耒阳市| 巩留县| 郧西县| 应用必备| 汶上县| 福贡县|