(轉(zhuǎn)) Java EJB到底是什么?

1. 我們不禁要問(wèn),什么是"服務(wù)集群"?什么是"企業(yè)級(jí)開發(fā)"?

既然說(shuō)了EJB 是為了"服務(wù)集群"和"企業(yè)級(jí)開發(fā)",那么,總得說(shuō)說(shuō)什么是所謂的"服務(wù)

集群"和"企業(yè)級(jí)開發(fā)"吧!

這個(gè)問(wèn)題其實(shí)挺關(guān)鍵的,因?yàn)镴2EE 中并沒有說(shuō)明白,也沒有具體的指標(biāo)或者事例告訴

廣大程序員什么時(shí)候用EJB 什么時(shí)候不用。于是大家都產(chǎn)生一些聯(lián)想,認(rèn)為EJB"分布式運(yùn)

算"指得是"負(fù)載均衡"提高系統(tǒng)的運(yùn)行效率。然而,估計(jì)很多人都搞錯(cuò)了,這個(gè)"服務(wù)群集"

和"分布式運(yùn)算"并沒有根本解決運(yùn)行負(fù)載的問(wèn)題,尤其是針對(duì)數(shù)據(jù)庫(kù)的應(yīng)用系統(tǒng)。

為什么?

我們先把EJB 打回原形給大家來(lái)慢慢分析。

2.?把EJB 掰開了揉碎了

我們把EJB 的概念好好的分析一下,看看能發(fā)現(xiàn)些什么蛛絲馬跡。

3.1?EJB 概念的剖析

我們先看一下,EJB 的官方解釋:

商務(wù)軟件的核心部分是它的業(yè)務(wù)邏輯。業(yè)務(wù)邏輯抽象了整個(gè)商務(wù)過(guò)程的流程,并使用計(jì)

算機(jī)語(yǔ)言將他們實(shí)現(xiàn)。

……

J2EE 對(duì)于這個(gè)問(wèn)題的處理方法是將業(yè)務(wù)邏輯從客戶端軟件中抽取出來(lái),封裝在一個(gè)組

件中。這個(gè)組件運(yùn)行在一個(gè)獨(dú)立的服務(wù)器上,客戶端軟件通過(guò)網(wǎng)絡(luò)調(diào)用組件提供的服務(wù)以實(shí)

現(xiàn)業(yè)務(wù)邏輯,而客戶端軟件的功能單純到只負(fù)責(zé)發(fā)送調(diào)用請(qǐng)求和顯示處理結(jié)果。在J2EE 中,

這個(gè)運(yùn)行在一個(gè)獨(dú)立的服務(wù)器上,并封裝了業(yè)務(wù)邏輯的組件就是EJB(EnterpriseJava

Bean)組件。

這其中我們主要關(guān)注這么幾點(diǎn),我們來(lái)逐條剖析:

剖析1:所謂:"業(yè)務(wù)邏輯"

我們注意到在EJB 的概念中主要提到的就是"業(yè)務(wù)邏輯"的封裝,而這個(gè)業(yè)務(wù)邏輯到底是

什么?說(shuō)的那么懸乎,其實(shí)這個(gè)所謂的"業(yè)務(wù)邏輯"我們完全可以理解成執(zhí)行特定任務(wù)的"類

"。

剖析2:所謂:"將業(yè)務(wù)邏輯從客戶端軟件中抽取出來(lái),封裝在組件中……運(yùn)行在一個(gè)服

務(wù)器上"

既然我們知道了"業(yè)務(wù)邏輯"的概念就是執(zhí)行特定任務(wù)的"類",那么,什么叫"從客戶端

軟件中抽取出來(lái)"?其實(shí),這個(gè)就是把原來(lái)放到客戶端的"類",拿出來(lái)不放到客戶端了,放

到一個(gè)組件中,并將這個(gè)組件放到一個(gè)服務(wù)器上去運(yùn)行。

3.2 把EJB 這個(gè)概念變成大白話

變成大白話就是,"把你編寫的軟件中那些需要執(zhí)行制定的任務(wù)的類,不放到客戶端軟

件上了,而是給他打成包放到一個(gè)服務(wù)器上了"。

3.3 發(fā)現(xiàn)問(wèn)題了

不管是用"八股文"說(shuō),還是用大白話說(shuō)這個(gè)EJB 概念都提到了一個(gè)詞--"客戶端軟件"。

"客戶端軟件"?難道EJB 的概念中說(shuō)的是C/S 軟件?

是的,沒錯(cuò)!

EJB 就是將那些"類"放到一個(gè)服務(wù)器上,用C/S 形式的軟件客戶端對(duì)服務(wù)器上的"類"進(jìn)

行調(diào)用。

快崩潰了吧!

EJB 和JSP 有什么關(guān)系?EJB 和JSP 有關(guān)系,但是關(guān)系還真不怎么大,至多是在JSP 的

服務(wù)器端調(diào)用遠(yuǎn)端服務(wù)上的EJB 類,僅此而已。

4.1 EJB 的最底層究竟是什么

我們揭開了EJB"八股"概念的真諦,那么,再來(lái)分析EJB 的底層實(shí)現(xiàn)技術(shù),通過(guò)底層實(shí)

現(xiàn)技術(shù)來(lái)分析EJB 的工作方式。

4.2 EJB 的實(shí)現(xiàn)技術(shù)

EJB 是運(yùn)行在獨(dú)立服務(wù)器上的組件,客戶端是通過(guò)網(wǎng)絡(luò)對(duì)EJB 對(duì)象進(jìn)行調(diào)用的。在Java

中,能夠?qū)崿F(xiàn)遠(yuǎn)程對(duì)象調(diào)用的技術(shù)是RMI,而EJB 技術(shù)基礎(chǔ)正是RMI。通過(guò)RMI 技術(shù),J2EE

將EJB 組件創(chuàng)建為遠(yuǎn)程對(duì)象,客戶端就可以通過(guò)網(wǎng)絡(luò)調(diào)用EJB 對(duì)象了。

4.3 看看RMI 是什么東東

在說(shuō)RMI 之前,需要理解兩個(gè)名詞:

對(duì)象的序列化

分布式計(jì)算與RPC

名詞1:對(duì)象的序列化

對(duì)象的序列化概念:對(duì)象的序列化過(guò)程就是將對(duì)象狀態(tài)轉(zhuǎn)換成字節(jié)流和從字節(jié)流恢復(fù)對(duì)

象。將對(duì)象狀態(tài)轉(zhuǎn)換成字節(jié)流之后,可以用java.io 包中的各種字節(jié)流類將其保存到文件中,

或者通過(guò)網(wǎng)絡(luò)連接將對(duì)象數(shù)據(jù)發(fā)送到另一個(gè)主機(jī)。

上面的說(shuō)法有點(diǎn)"八股",我們不妨再用白話解釋一下:對(duì)象的序列化就是將你程序中實(shí)

例化的某個(gè)類的對(duì)象,比如,你自定一個(gè)類MyClass,或者任何一個(gè)類的對(duì)象,將它轉(zhuǎn)換成

字節(jié)數(shù)組,也就是說(shuō)可以放到一個(gè)byte 數(shù)組中,這時(shí)候,你既然已經(jīng)把一個(gè)對(duì)象放到了byte

數(shù)組中,那么你當(dāng)然就可以隨便處置了它了,用得最多的就是把他發(fā)送到網(wǎng)絡(luò)上遠(yuǎn)程的計(jì)算

機(jī)上了。如圖:

名詞2:分布式計(jì)算與RPC

RPC 并不是一個(gè)純粹的Java 概念,因?yàn)樵贘ava 誕生之前就已經(jīng)有了RPC 的這個(gè)概念,RPC

是"Remote Procedure Call"的縮寫,也就是"遠(yuǎn)程過(guò)程調(diào)用"。在Java 之前的大多數(shù)編程語(yǔ)

言,如,F(xiàn)ortran、C、COBOL 等等,都是過(guò)程性的語(yǔ)言,而不是面向?qū)ο蟮摹K?,這些編

程語(yǔ)言很自然地用過(guò)程表示工作,如,函數(shù)或子程序,讓其在網(wǎng)絡(luò)上另一臺(tái)機(jī)器上執(zhí)行。說(shuō)

白了,就是本地計(jì)算機(jī)調(diào)用遠(yuǎn)程計(jì)算機(jī)上的一個(gè)函數(shù)。

如圖:

名詞3:二者結(jié)合就是RMI

RMI 英文全稱是"Remote Method Invocation",它的中文名稱是"遠(yuǎn)程方法調(diào)用",它就

是利用Java 對(duì)象序列化的機(jī)制實(shí)現(xiàn)分布式計(jì)算,實(shí)現(xiàn)遠(yuǎn)程類對(duì)象的實(shí)例化以及調(diào)用的方法。

說(shuō)的更清楚些,就是利用對(duì)象序列化來(lái)實(shí)現(xiàn)遠(yuǎn)程調(diào)用,也就是上面兩個(gè)概念的結(jié)合體,利用

這個(gè)方法來(lái)調(diào)用遠(yuǎn)程的類的時(shí)候,就不需要編寫Socket 程序了,也不需要把對(duì)象進(jìn)行序列

化操作,直接調(diào)用就行了非常方便。

遠(yuǎn)程方法調(diào)用是一種計(jì)算機(jī)之間對(duì)象互相調(diào)用對(duì)方函數(shù),啟動(dòng)對(duì)方進(jìn)程的一種機(jī)制,使用這

種機(jī)制,某一臺(tái)計(jì)算機(jī)上的對(duì)象在調(diào)用另外一臺(tái)計(jì)算機(jī)上的方法時(shí),使用的程序語(yǔ)法規(guī)則和

在本地機(jī)上對(duì)象間的方法調(diào)用的語(yǔ)法規(guī)則一樣。

如圖:

4.4 優(yōu)點(diǎn)

這種機(jī)制給分布計(jì)算的系統(tǒng)設(shè)計(jì)、編程都帶來(lái)了極大的方便。只要按照RMI 規(guī)則設(shè)計(jì)程

序,可以不必再過(guò)問(wèn)在RMI 之下的網(wǎng)絡(luò)細(xì)節(jié)了,如:TCP 和Socket 等等。任意兩臺(tái)計(jì)算機(jī)

之間的通訊完全由RMI 負(fù)責(zé)。調(diào)用遠(yuǎn)程計(jì)算機(jī)上的對(duì)象就像本地對(duì)象一樣方便。

RMI 可將完整的對(duì)象作為參數(shù)和返回值進(jìn)行傳遞,而不僅僅是預(yù)定義的數(shù)據(jù)類型。也就

是說(shuō),可以將類似Java 哈西表這樣的復(fù)雜類型作為一個(gè)參數(shù)進(jìn)行傳遞。

4.5 缺點(diǎn)

如果是較為簡(jiǎn)單的方法調(diào)用,其執(zhí)行效率也許會(huì)比本地執(zhí)行慢很多,即使和遠(yuǎn)程Socket

機(jī)制的簡(jiǎn)單數(shù)據(jù)返回的應(yīng)用相比,也會(huì)慢一些,原因是,其在網(wǎng)絡(luò)間需要傳遞的信息不僅僅

包含該函數(shù)的返回值信息,還會(huì)包含該對(duì)象序列化后的字節(jié)內(nèi)容。

4.6 EJB 是以RMI 為基礎(chǔ)的

通過(guò)RMI 技術(shù),J2EE 將EJB 組件創(chuàng)建為遠(yuǎn)程對(duì)象,EJB 雖然用了RMI 技術(shù),但是卻只需

要定義遠(yuǎn)程接口而無(wú)需生成他們的實(shí)現(xiàn)類,這樣就將RMI 技術(shù)中的一些細(xì)節(jié)問(wèn)題屏蔽了。

但不管怎么說(shuō),EJB 的基礎(chǔ)仍然是RMI,所以,如果你想了解EJB 的原理,只要把RMI

的原理搞清楚就行了。你也就弄清楚了什么時(shí)候用EJB 什么時(shí)候不需要用EJB 了。

5.?EJB 中所謂的"服務(wù)群集"

既然已經(jīng)知道了,RMI 是將各種任務(wù)與功能的類放到不同的服務(wù)器上,然后通過(guò)各個(gè)服

務(wù)器間建立的調(diào)用規(guī)則實(shí)現(xiàn)分布式的運(yùn)算,也就明白EJB 所謂的"服務(wù)群集"的概念。

就是將原來(lái)在一個(gè)計(jì)算機(jī)上運(yùn)算的幾個(gè)類,分別放到其他計(jì)算機(jī)上去運(yùn)行,以便分擔(dān)運(yùn)

行這幾個(gè)類所需要占用的CPU 和內(nèi)存資源。同時(shí),也可以將不同的軟件功能模塊放到不同的

服務(wù)器上,當(dāng)需要修改某些功能的時(shí)候直接修改這些服務(wù)器上的類就行了,修改以后所有客

戶端的軟件都被修改了。如圖:

6.?這種部署難道是無(wú)懈可擊

上圖所示的這個(gè)"服務(wù)群集"看似"無(wú)懈可擊",其實(shí)是它這個(gè)圖沒有畫完整,我們來(lái)

把這個(gè)圖畫完整,再來(lái)看看有什么問(wèn)題沒有。

6.1 瓶頸在數(shù)據(jù)庫(kù)端

仔細(xì)觀察之后,發(fā)現(xiàn)這種配置是有瓶頸的,如圖:

我們看看上圖的結(jié)構(gòu)圖,現(xiàn)在如果想實(shí)現(xiàn)各個(gè)服務(wù)器針對(duì)同一個(gè)數(shù)據(jù)庫(kù)的查詢,那

么,不管你部署多少個(gè)功能服務(wù)器,都需要針對(duì)一個(gè)數(shù)據(jù)庫(kù)服務(wù)器進(jìn)行查詢操作。也就是說(shuō),

不管你的"計(jì)算"有多么"分布"也同樣需要從一臺(tái)服務(wù)器中取得數(shù)據(jù)。雖然,看起來(lái)將各個(gè)功

能模塊分布在不同的服務(wù)器上從而分擔(dān)了各個(gè)主計(jì)算機(jī)的CPU 資源,然而,真正的瓶頸并不

在這里,而是,數(shù)據(jù)庫(kù)服務(wù)器那里。數(shù)據(jù)庫(kù)服務(wù)器都會(huì)非常忙的應(yīng)付各個(gè)服務(wù)器的查詢及操

作請(qǐng)求。

因此,通過(guò)這個(gè)結(jié)構(gòu)圖使我們了解到了EJB 根本不能完全解決負(fù)載的問(wèn)題,因?yàn)椋款i

并不在功能模塊的所在位置,而是在數(shù)據(jù)庫(kù)服務(wù)器這里。

6.2 假如分開數(shù)據(jù)庫(kù),數(shù)據(jù)共享怎么辦

有的讀者一定會(huì)想到下面的這個(gè)應(yīng)用結(jié)構(gòu),如圖:

就是把每一個(gè)功能服務(wù)器后面都部署一個(gè)數(shù)據(jù)庫(kù),這樣不就解決了上節(jié)所說(shuō)的問(wèn)題了

嗎?是的解決了數(shù)據(jù)庫(kù)查詢負(fù)載的問(wèn)題,然而又出現(xiàn)了新的問(wèn)題,就是"數(shù)據(jù)共享"的問(wèn)題就

又不容易解決了。

6.3 網(wǎng)絡(luò)面臨較大壓力,讓你的應(yīng)用慢如老牛

我們?cè)傧蚯胺纯慈缟蠄D所示的這種架構(gòu)中存在兩個(gè)網(wǎng)絡(luò),一個(gè)是"A 網(wǎng)"一個(gè)是"B

網(wǎng)",這兩個(gè)網(wǎng)絡(luò)是不同的。"B 網(wǎng)"往往是局域網(wǎng),一般帶寬是10M/100M,速度較快,因此

到還好說(shuō),然而,"A 網(wǎng)"往往是互聯(lián)網(wǎng)或者是利用電信網(wǎng)絡(luò)互聯(lián)VPN 網(wǎng)或稱廣域網(wǎng)。"A 網(wǎng)"

的特點(diǎn)是帶寬一般較窄,如ADSL 的網(wǎng)絡(luò)僅僅有512K-2M 的帶寬,由于廣域網(wǎng)互聯(lián)的成本較

高,所以一般不會(huì)有較高的帶寬。

而在這個(gè)網(wǎng)絡(luò)上恰恰跑的是功能模塊和客戶端軟件之間交換的數(shù)據(jù),而這部分?jǐn)?shù)據(jù)恰恰

優(yōu)勢(shì)非常占用帶寬的。

因此,這個(gè)應(yīng)用架構(gòu)其運(yùn)行速度可以想見是多么的慢了。說(shuō)句不夸張的話,有點(diǎn)想老牛

拉破車一樣的慢。

一個(gè)如老牛的系統(tǒng):

目前在中國(guó)互聯(lián)網(wǎng)做運(yùn)營(yíng)商網(wǎng)絡(luò)管理系統(tǒng)的一個(gè)大公司,它的一個(gè)早期的網(wǎng)管軟件就是

采用了這種架構(gòu)來(lái)做的C/S 結(jié)構(gòu)的應(yīng)用系統(tǒng)。

有一次,我作為評(píng)估者來(lái)對(duì)其應(yīng)用系統(tǒng)進(jìn)行評(píng)估,將其部署到一個(gè)非運(yùn)營(yíng)商大型的網(wǎng)絡(luò)

中的時(shí)候,便出現(xiàn)了我們上述描述的情況,速度已經(jīng)到了難以忍受的地步,打開一個(gè)流量圖,

有時(shí)候需要用15分鐘的時(shí)間才能呈現(xiàn)完整。然而,該系統(tǒng)在開發(fā)階段并沒有發(fā)現(xiàn)這個(gè)問(wèn)題,

為什么呢?因?yàn)?,他們沒有考慮到應(yīng)用的實(shí)際用戶連接網(wǎng)絡(luò)的復(fù)雜性,從而給該公司造成較

大損失,以至于,這個(gè)開發(fā)架構(gòu)被最終遺棄。

7.?EJB 活學(xué)活用,J2EE 不是必須使用EJB

通過(guò)上面小節(jié)的講解似乎好像EJB 和開發(fā)Web 應(yīng)用的B/S 結(jié)構(gòu)的系統(tǒng)關(guān)系并不大,其實(shí)

倒也不然。我們?nèi)绻?客戶端程序"理解成某一臺(tái)服務(wù)器,這樣也是可以被應(yīng)用的,而且,

如果是服務(wù)器互相之間做EJB 的調(diào)用的話,也就不存在廣域網(wǎng)帶寬限制的問(wèn)題了。

但是,如下情況盡量就不要使用EJB 了:

1、較為簡(jiǎn)單的純Web 應(yīng)用開發(fā),不需要用EJB。

2、需要與其他服務(wù)程序配合使用的應(yīng)用,但調(diào)用或返回的自定義的網(wǎng)絡(luò)協(xié)議可以解決

的應(yīng)用程序,不需要使用EJB。

3、較多人并發(fā)訪問(wèn)的C/S 結(jié)構(gòu)的應(yīng)用程序,盡量不要使用EJB。

總結(jié):

a.EJB實(shí)現(xiàn)原理:就是把原來(lái)放到客戶端實(shí)現(xiàn)的代碼放到服務(wù)器端,并依靠RMI進(jìn)行通信。

b.RMI實(shí)現(xiàn)原理:就是通過(guò)Java對(duì)象可序列化機(jī)制實(shí)現(xiàn)分布計(jì)算。

c.服務(wù)器集群:就是通過(guò)RMI的通信,連接不同功能模塊的服務(wù)器,以實(shí)現(xiàn)一個(gè)完整的功能。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,011評(píng)論 0 11
  • 1、面向?qū)ο蟮奶卣饔心男┓矫?1.抽象:抽象就是忽略一個(gè)主題中與當(dāng)前目標(biāo)無(wú)關(guān)的那些方面,以便更充分地注意與當(dāng)前目標(biāo)...
    michaelgong閱讀 920評(píng)論 0 1
  • JAVA相關(guān)基礎(chǔ)知識(shí) 1、面向?qū)ο蟮奶卣饔心男┓矫?1.抽象: 抽象就是忽略一個(gè)主題中與當(dāng)前目標(biāo)無(wú)關(guān)的那些方面,以...
    yangkg閱讀 746評(píng)論 0 1
  • 小編費(fèi)力收集:給你想要的面試集合 1.C++或Java中的異常處理機(jī)制的簡(jiǎn)單原理和應(yīng)用。 當(dāng)JAVA程序違反了JA...
    八爺君閱讀 5,182評(píng)論 1 114
  • 面向?qū)ο缶幊蹋∣OP) Java是一個(gè)支持并發(fā)、基于類和面向?qū)ο蟮挠?jì)算機(jī)編程語(yǔ)言。下面列出了面向?qū)ο筌浖_發(fā)的優(yōu)點(diǎn)...
    大家請(qǐng)叫我小杰閱讀 1,208評(píng)論 0 0

友情鏈接更多精彩內(nèi)容