1. 我們不禁要問,什麼是"服務叢集"?什麼是"企業級開發"? 


既然說了EJB 是為了"服務叢集"和"企業級開發",那麼,總得說說什麼是所謂的"服務叢集"和"企業級開發"吧!這個問題其實挺關鍵的,因為J2EE 中並沒有說明白,也沒有具體的指標或者事例告訴廣大程式設計師什麼時候用EJB 什麼時候不用。於是大家都產生一些聯想,認為EJB"分散式運算"指得是"負載均衡"提高系統的執行效率。然而,估計很多人都搞錯了,這個"服務群集"和"分散式運算"並沒有根本解決執行負載的問題,尤其是針對資料庫的應用系統。
為什麼?

我們先把EJB 打回原形給大家來慢慢分析。


2. 把EJB 掰開了揉碎了 


我們把EJB 的概念好好的分析一下,看看能發現些什麼蛛絲馬跡。


3.1 EJB 概念的剖析


我們先看一下,EJB 的官方解釋:
商務軟體的核心部分是它的業務邏輯。業務邏輯抽象了整個商務過程的流程,並使用計算機語言將他們實現。
……
J2EE 對於這個問題的處理方法是將業務邏輯從客戶端軟體中抽取出來,封裝在一個元件中。這個元件執行在一個獨立的伺服器上,客戶端軟體通過網路呼叫元件提供的服務以實現業務邏輯,而客戶端軟體的功能單純到只負責傳送呼叫請求和顯示處理結果。在J2EE 中,這個執行在一個獨立的伺服器上,並封裝了業務邏輯的元件就是EJB(Enterprise JavaBean)元件。這其中我們主要關注這麼幾點,我們來逐條剖析:

剖析1:所謂:"業務邏輯" 
我們注意到在EJB 的概念中主要提到的就是"業務邏輯"的封裝,而這個業務邏輯到底是什麼?說的那麼懸乎,其實這個所謂的"業務邏輯"我們完全可以理解成執行特定任務的"類"。


剖析2:所謂:"將業務邏輯從客戶端軟體中抽取出來,封裝在元件中……執行在一個伺服器上"
既然我們知道了"業務邏輯"的概念就是執行特定任務的"類",那麼,什麼叫"從客戶端軟體中抽取出來"?其實,這個就是把原來放到客戶端的"類",拿出來不放到客戶端了,放到一個元件中,並將這個元件放到一個伺服器上去執行。


3.2 把EJB 這個概念變成大白話 


變成大白話就是,"把你編寫的軟體中那些需要執行制定的任務的類,不放到客戶端軟體上了,而是給他打成包放到一個伺服器上了"。


3.3 發現問題了 


不管是用"八股文"說,還是用大白話說這個EJB 概念都提到了一個詞--"客戶端軟體"。
"客戶端軟體"?難道EJB 的概念中說的是C/S 軟體?
是的,沒錯!
EJB 就是將那些"類"放到一個伺服器上,用C/S 形式的軟體客戶端對伺服器上的"類"進行呼叫。
快崩潰了吧!
EJB 和JSP 有什麼關係?EJB 和JSP 有關係,但是關係還真不怎麼大,至多是在JSP 的伺服器端呼叫遠端服務上的EJB 類,僅此而已。


4 .1 EJB 的最底層究竟是什麼 


我們揭開了EJB"八股"概念的真諦,那麼,再來分析EJB 的底層實現技術,通過底層實
現技術來分析EJB 的工作方式。


4.2 EJB 的實現技術


EJB 是執行在獨立伺服器上的元件,客戶端是通過網路對EJB 物件進行呼叫的。在Java中,能夠實現遠端物件呼叫的技術是RMI,而EJB 技術基礎正是RMI。通過RMI 技術,J2EE將EJB 元件建立為遠端物件,客戶端就可以通過網路呼叫EJB 物件了。


4.3 看看RMI 是什麼東東 


在說RMI 之前,需要理解兩個名詞:
物件的序列化
分散式計算與RPC


名詞1:物件的序列化 
物件的序列化概念:物件的序列化過程就是將物件狀態轉換成位元組流和從位元組流恢復物件。將物件狀態轉換成位元組流之後,可以用java.io 包中的各種位元組流類將其儲存到檔案中,或者通過網路連線將物件資料傳送到另一個主機。
上面的說法有點"八股",我們不妨再用白話解釋一下:物件的序列化就是將你程式中例項化的某個類的物件,比如,你自定一個類MyClass,或者任何一個類的物件,將它轉換成位元組陣列,也就是說可以放到一個byte 陣列中,這時候,你既然已經把一個物件放到了byte陣列中,那麼你當然就可以隨便處置了它了,用得最多的就是把他傳送到網路上遠端的計算機上了。如圖2 11所示。

 
名詞2:分散式計算與RPC 
RPC 並不是一個純粹的Java 概念,因為在Java 誕生之前就已經有了RPC 的這個概念,RPC是"Remote Procedure Call"的縮寫,也就是"遠端過程呼叫"。在Java 之前的大多數程式語言,如,Fortran、C、COBOL 等等,都是過程性的語言,而不是面向物件的。所以,這些程式語言很自然地用過程表示工作,如,函式或子程式,讓其在網路上另一臺機器上執行。說白了,就是本地計算機呼叫遠端計算機上的一個函式。如圖2 12所示。

 
名詞3:二者結合就是RMI 
RMI 英文全稱是"Remote Method Invocation",它的中文名稱是"遠端方法呼叫",它就是利用Java 物件序列化的機制實現分散式計算,實現遠端類物件的例項化以及呼叫的方法。說的更清楚些,就是利用物件序列化來實現遠端呼叫,也就是上面兩個概念的結合體,利用這個方法來呼叫遠端的類的時候,就不需要編寫Socket 程式了,也不需要把物件進行序列化操作,直接呼叫就行了非常方便。
遠端方法呼叫是一種計算機之間物件互相呼叫對方函式,啟動對方程序的一種機制,使用這種機制,某一臺計算機上的物件在呼叫另外一臺計算機上的方法時,使用的程式語法規則和在本地機上物件間的方法呼叫的語法規則一樣。如圖2 13所示。

4.4 優點


這種機制給分佈計算的系統設計、程式設計都帶來了極大的方便。只要按照RMI 規則設計程式,可以不必再過問在RMI 之下的網路細節了,如:TCP 和Socket 等等。任意兩臺計算機之間的通訊完全由RMI 負責。呼叫遠端計算機上的物件就像本地物件一樣方便。RMI 可將完整的物件作為引數和返回值進行傳遞,而不僅僅是預定義的資料型別。也就是說,可以將類似Java 哈西表這樣的複雜型別作為一個引數進行傳遞。


4.5 缺點 


如果是較為簡單的方法呼叫,其執行效率也許會比本地執行慢很多,即使和遠端Socket機制的簡單資料返回的應用相比,也會慢一些,原因是,其在網路間需要傳遞的資訊不僅僅包含該函式的返回值資訊,還會包含該物件序列化後的位元組內容。


4.6 EJB 是以RMI 為基礎的

通過RMI 技術,J2EE 將EJB 元件建立為遠端物件,EJB 雖然用了RMI 技術,但是卻只需要定義遠端介面而無需生成他們的實現類,這樣就將RMI 技術中的一些細節問題遮蔽了。但不管怎麼說,EJB 的基礎仍然是RMI,所以,如果你想了解EJB 的原理,只要把RMI的原理搞清楚就行了。你也就弄清楚了什麼時候用EJB 什麼時候不需要用EJB 了。


5. EJB 中所謂的"服務群集" 


既然已經知道了,RMI 是將各種任務與功能的類放到不同的伺服器上,然後通過各個伺服器間建立的呼叫規則實現分散式的運算,也就明白EJB 所謂的"服務群集"的概念。就是將原來在一個計算機上運算的幾個類,分別放到其他計算機上去執行,以便分擔執行這幾個類所需要佔用的CPU 和記憶體資源。同時,也可以將不同的軟體功能模組放到不同的伺服器上,當需要修改某些功能的時候直接修改這些伺服器上的類就行了,修改以後所有客戶端的軟體都被修改了。如圖2 14所示。

6. 這種部署難道是無懈可擊 


圖2 14所示的這個"服務群集"看似"無懈可擊",其實是它這個圖沒有畫完整,我們來把這個圖畫完整,再來看看有什麼問題沒有。


6.1 瓶頸在資料庫端 


仔細觀察之後,發現這種配置是有瓶頸的,如圖2 15所示。

 
我們看看圖2 15的結構圖,現在如果想實現各個伺服器針對同一個資料庫的查詢,那麼,不管你部署多少個功能伺服器,都需要針對一個數據庫伺服器進行查詢操作。也就是說,不管你的"計算"有多麼"分佈"也同樣需要從一臺伺服器中取得資料。雖然,看起來將各個功能模組分佈在不同的伺服器上從而分擔了各個主計算機的CPU 資源,然而,真正的瓶頸並不在這裡,而是,資料庫伺服器那裡。資料庫伺服器都會非常忙的應付各個伺服器的查詢及操作請求。
因此,通過這個結構圖使我們瞭解到了EJB 根本不能完全解決負載的問題,因為,瓶頸並不在功能模組的所在位置,而是在資料庫伺服器這裡。


6.2 假如分開資料庫,資料共享怎麼辦 


有的讀者一定會想到下面的這個應用結構,如圖2 16所示。

 
就是把每一個功能伺服器後面都部署一個數據庫,這樣不就解決了上節所說的問題了嗎?是的解決了資料庫查詢負載的問題,然而又出現了新的問題,就是"資料共享"的問題就又不容易解決了。


6.3 網路面臨較大壓力,讓你的應用慢如老牛

我們再向前翻看看如圖2 15所示的這種架構中存在兩個網路,一個是"A 網"一個是"B網",這兩個網路是不同的。"B 網"往往是區域網,一般頻寬是10M/100M,速度較快,因此到還好說,然而,"A 網"往往是網際網路或者是利用電信網路互聯VPN 網或稱廣域網。"A 網"的特點是頻寬一般較窄,如ADSL 的網路僅僅有512K-2M 的頻寬,由於廣域網互聯的成本較高,所以一般不會有較高的頻寬。而在這個網路上恰恰跑的是功能模組和客戶端軟體之間交換的資料,而這部分資料恰恰優勢非常佔用頻寬的。因此,這個應用架構其執行速度可以想見是多麼的慢了。說句不誇張的話,有點想老牛拉破車一樣的慢。一個如老牛的系統:目前在中國網際網路做運營商網路管理系統的一個大公司,它的一個早期的網管軟體就是採用了這種架構來做的C/S 結構的應用系統。有一次,我作為評估者來對其應用系統進行評估,將其部署到一個非運營商大型的網路中的時候,便出現了我們上述描述的情況,速度已經到了難以忍受的地步,開啟一個流量圖,有時候需要用15分鐘的時間才能呈現完整。然而,該系統在開發階段並沒有發現這個問題,為什麼呢?因為,他們沒有考慮到應用的實際使用者連線網路的複雜性,從而給該公司造成較大損失,以至於,這個開發架構被最終遺棄。

7. EJB 活學活用,J2EE 不是必須使用EJB 


通過上面小節的講解似乎好像EJB 和開發Web 應用的B/S 結構的系統關係並不大,其實倒也不然。我們如果把"客戶端程式"理解成某一臺伺服器,這樣也是可以被應用的,而且,如果是伺服器互相之間做EJB 的呼叫的話,也就不存在廣域網頻寬限制的問題了。
但是,如下情況儘量就不要使用EJB 了:
1、較為簡單的純Web 應用開發,不需要用EJB。
2、需要與其他服務程式配合使用的應用,但呼叫或返回的自定義的網路協議可以解決的應用程式,不需要使用EJB。
3、較多人併發訪問的C/S 結構的應用程式,儘量不要使用EJB。

總結:

a.EJB實現原理: 就是把原來放到客戶端實現的程式碼放到伺服器端,並依靠RMI進行通訊。

b.RMI實現原理 :就是通過Java物件可序列化機制實現分佈計算。

c.伺服器叢集: 就是通過RMI的通訊,連線不同功能模組的伺服器,以實現一個完整的功能。

文章轉自 http://blog.csdn.net/jojo52013145/article/details/5783677