引用源:http://blog.csdn.NET/cymm_liu/article/details/7760989
1、EJB 概念的剖析 我們先看一下,EJB 的官方解釋: 商務軟件的核心部分是它的業務邏輯。業務邏輯抽象了整個商務過程的流程,並使用計算機語言將他們實現。 …… J2EE 對於這個問題的處理方法是將業務邏輯從客戶端軟件中抽取出來,封裝在一個組件中。這個組件運行在一個獨立的服務器上,客戶端軟件通過網絡調用組件提供的服務以實現業務邏輯,而客戶端軟件的功能單純到只負責發送調用請求和顯示處理結果。在J2EE 中,這個運行在一個獨立的服務器上,並封裝了業務邏輯的組件就是EJB(Enterprise JavaBean)組件。
這其中我們主要關注這么幾點,我們來逐條剖析:
剖析1:所謂:"業務邏輯" 我們注意到在EJB 的概念中主要提到的就是"業務邏輯"的封裝,而這個業務邏輯到底是什么?說的那么懸乎,其實這個所謂的"業務邏輯"我們完全可以理解成執行特定任務的"類"。
剖析2:所謂:"將業務邏輯從客戶端軟件中抽取出來,封裝在組件中……運行在一個服務器上" 既然我們知道了"業務邏輯"的概念就是執行特定任務的"類",那么,什么叫"從客戶端軟件中抽取出來"?其實,這個就是把原來放到客戶端的"類",拿出來不放到客戶端了,放到一個組件中,並將這個組件放到一個服務器上去運行。
把EJB 這個概念變成大白話 : 變成大白話就是,"把你編寫的軟件中那些需要執行制定的任務的類,不放到客戶端軟件上了,而是給他打成包放到一個服務器上了"。 發現問題了 :不管是用"八股文"說,還是用大白話說這個EJB 概念都提到了一個詞--"客戶端軟件"。"客戶端軟件"?難道EJB 的概念中說的是C/S 軟件? 是的,沒錯! EJB 就是將那些"類"放到一個服務器上,用C/S 形式的軟件客戶端對服務器上的"類"進行調用。 快崩潰了吧!
EJB 和JSP 有什么關系?
EJB 和JSP 有關系,但是關系還真不怎么大,至多是在JSP 的服務器端調用遠端服務上的EJB 類,僅此而已。
2、 EJB 的最底層究竟是什么 我們揭開了EJB"八股"概念的真諦,那么,再來分析EJB 的底層實現技術,通過底層實現技術來分析EJB 的工作方式。
EJB 的實現技術: EJB 是運行在獨立服務器上的組件,客戶端是通過網絡對EJB 對象進行調用的。在Java中,能夠實現遠程對象調用的技術是RMI,而EJB 技術基礎正是RMI。通過RMI 技術,J2EE將EJB 組件創建為遠程對象,客戶端就可以通過網絡調用EJB 對象了。
看看RMI 是什么東東 : 在說RMI 之前,需要理解兩個名詞:對象的序列化 分布式計算與RPC 名詞1:對象的序列化 對象的序列化概念:對象的序列化過程就是將對象狀態轉換成字節流和從字節流恢復對象。將對象狀態轉換成字節流之后,可以用java.io 包中的各種字節流類將其保存到文件中,或者通過網絡連接將對象數據發送到另一個主機。上面的說法有點"八股",我們不妨再用白話解釋一下:對象的序列化就是將你程序中實 例化的某個類的對象,比如,你自定一個類MyClass,或者任何一個類的對象,將它轉換成字節數組,也就是說可以放到一個byte 數組中,這時候,你既然已經把一個對象放到了byte數組中,那么你當然就可以隨便處置了它了,用得最多的就是把他發送到網絡上遠程的計算機上了。如圖所示:
名詞2:分布式計算與RPC
RPC 並不是一個純粹的Java 概念,因為在Java 誕生之前就已經有了RPC 的這個概念,RPC是"Remote Procedure Call"的縮寫,也就是"遠程過程調用"。在Java 之前的大多數編程語言,如,Fortran、C、COBOL 等等,都是過程性的語言,而不是面向對象的。所以,這些編程語言很自然地用過程表示工作,如,函數或子程序,讓其在網絡上另一台機器上執行。說白了,就是本地計算機調用遠程計算機上的一個函數。
如圖下所示:
名詞3:二者結合就是RMI
RMI 英文全稱是"Remote Method Invocation",它的中文名稱是"遠程方法調用",它就是利用Java 對象序列化的機制實現分布式計算,實現遠程類對象的實例化以及調用的方法。說的更清楚些,就是利用對象序列化來實現遠程調用,也就是上面兩個概念的結合體,利用這個方法來調用遠程的類的時候,就不需要編寫Socket 程序了,也不需要把對象進行序列化操作,直接調用就行了非常方便。
遠程方法調用是一種計算機之間對象互相調用對方函數,啟動對方進程的一種機制,使用這種機制,某一台計算機上的對象在調用另外一台計算機上的方法時,使用的程序語法規則和在本地機上對象間的方法調用的語法規則一樣。
如圖下所示:
優點: 這種機制給分布計算的系統設計、編程都帶來了極大的方便。只要按照RMI 規則設計程序,可以不必再過問在RMI 之下的網絡細節了,如:TCP 和Socket 等等。任意兩台計算機之間的通訊完全由RMI 負責。調用遠程計算機上的對象就像本地對象一樣方便。 RMI 可將完整的對象作為參數和返回值進行傳遞,而不僅僅是預定義的數據類型。也就是說,可以將類似Java 哈西表這樣的復雜類型作為一個參數進行傳遞。 缺點: 如果是較為簡單的方法調用,其執行效率也許會比本地執行慢很多,即使和遠程Socket機制的簡單數據返回的應用相比,也會慢一些,原因是,其在網絡間需要傳遞的信息不僅僅包含該函數的返回值信息,還會包含該對象序列化后的字節內容。
EJB 是以RMI 為基礎的 通過RMI 技術,J2EE 將EJB 組件創建為遠程對象,EJB 雖然用了RMI 技術,但是卻只需要定義遠程接口而無需生成他們的實現類,這樣就將RMI 技術中的一些細節問題屏蔽了。但不管怎么說,EJB 的基礎仍然是RMI,所以,如果你想了解EJB 的原理,只要把RMI的原理搞清楚就行了。你也就弄清楚了什么時候用EJB 什么時候不需要用EJB 了。
3、EJB 中所謂的"服務群集" 既然已經知道了,RMI 是將各種任務與功能的類放到不同的服務器上,然后通過各個服務器間建立的調用規則實現分布式的運算,也就明白EJB 所謂的"服務群集"的概念。 就是將原來在一個計算機上運算的幾個類,分別放到其他計算機上去運行,以便分擔運行這幾個類所需要占用的CPU 和內存資源。同時,也可以將不同的軟件功能模塊放到不同的服務器上,當需要修改某些功能的時候直接修改這些服務器上的類就行了,修改以后所有客戶端的軟件都被修改了。如圖下所示:
這種部署難道是無懈可擊 ?
圖上所示的這個"服務群集"看似"無懈可擊",其實是它這個圖沒有畫完整,我們來把這個圖畫完整,再來看看有什么問題沒有。
瓶頸在數據庫端 !
圖2 15
仔細觀察之后,發現這種配置是有瓶頸的。我們看看上圖的結構圖,現在如果想實現各個服務器針對同一個數據庫的查詢,那么,不管你部署多少個功能服務器,都需要針對一個數據庫服務器進行查詢操作。也就是說,不管你的"計算"有多么"分布"也同樣需要從一台服務器中取得數據。雖然,看起來將各個功能模塊分布在不同的服務器上從而分擔了各個主計算機的CPU 資源,然而,真正的瓶頸並不在這里,而是,數據庫服務器那里。數據庫服務器都會非常忙的應付各個服務器的查詢及操作請求。
因此,通過這個結構圖使我們了解到了EJB 根本不能完全解決負載的問題,因為,瓶頸並不在功能模塊的所在位置,而是在數據庫服務器這里。
假如分開數據庫,數據共享怎么辦 ? 有的讀者一定會想到下面的這個應用結構,如圖所示。
就是把每一個功能服務器后面都部署一個數據庫,這樣不就解決了上節所說的問題了嗎?是的解決了數據庫查詢負載的問題,然而又出現了新的問題,就是"數據共享"的問題就又不容易解決了。
網絡面臨較大壓力,讓你的應用慢如老牛: 我們再向前翻看看如圖2 15所示的這種架構中存在兩個網絡,一個是"A 網"一個是"B網",這兩個網絡是不同的。"B 網"往往是局域網,一般帶寬是10M/100M,速度較快,因此到還好說,然而,"A 網"往往是互聯網或者是利用電信網絡互聯VPN 網或稱廣域網。"A 網"的特點是帶寬一般較窄,如ADSL 的網絡僅僅有512K-4M 的帶寬,由於廣域網互聯的成本較高,所以一般不會有較高的帶寬。而在這個網絡上恰恰跑的是功能模塊和客戶端軟件之間交換的數據,而這部分數據恰恰 優勢非常占用帶寬的。因此,這個應用架構其運行速度可以想見是多么的慢了。說句不誇張的話,有點想老牛拉破車一樣的慢。 一個如老牛的系統: 目前在中國互聯網做運營商網絡管理系統的一個大公司,它的一個早期的網管軟件就是采用了這種架構來做的C/S 結構的應用系統。有一次,我作為評估者來對其應用系統進行評估,將其部署到一個非運營商大型的網絡中的時候,便出現了我們上述描述的情況,速度已經到了難以忍受的地步,打開一個流量圖, 有時候需要用15分鍾的時間才能呈現完整。然而,該系統在開發階段並沒有發現這個問題,為什么呢?因為,他們沒有考慮到應用的實際用戶連接網絡的復雜性,從而給該公司造成較大損失,以至於,這個開發架構被最終遺棄。
4、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的通信,連接不同功能模塊的服務器,以實現一個完整的功能。