遠(yuǎn)程方法調(diào)用RMI

文章轉(zhuǎn)載https://network.51cto.com/art/201906/598227.htm?mobile
RMI的定義

RPC (Remote Procedure Call):遠(yuǎn)程方法調(diào)用谷朝,用于一個(gè)進(jìn)程調(diào)用另一個(gè)進(jìn)程中的過程,從而提供了過程的分布能力武花。

RMI(Remote Method Invocation):遠(yuǎn)程方法調(diào)用圆凰,即在RPC的基礎(chǔ)上有向前邁進(jìn)了一步,提供分布式對象間的通訊体箕。允許運(yùn)行在一個(gè)java 虛擬機(jī)的對象調(diào)用運(yùn)行在另一個(gè)java虛擬機(jī)上對象的方法专钉。這兩個(gè)虛擬機(jī)可以是運(yùn)行在相同計(jì)算機(jī)上的不同進(jìn)程中,也可以是運(yùn)行在網(wǎng)絡(luò)上的不同計(jì)算機(jī)中累铅。

RMI的全稱宗旨就是盡量簡化遠(yuǎn)程接口對象的調(diào)用跃须。

RMI大大增強(qiáng)了java開發(fā)分布式應(yīng)用的能力,例如可以將計(jì)算方法復(fù)雜的程序放在其他的服務(wù)器上娃兽,主服務(wù)器只需要去調(diào)用菇民,而真正的運(yùn)算是在其他服務(wù)器上進(jìn)行,***將運(yùn)算結(jié)果返回給主服務(wù)器投储,這樣就減輕了主服務(wù)器的負(fù)擔(dān)第练,提高了效率(但是也有其他的開銷)。

RMI網(wǎng)絡(luò)模型

在設(shè)計(jì)初始階段玛荞,我們真正想要的是這樣一種機(jī)制复旬,客戶端程序員以常規(guī)方式進(jìn)行方法調(diào)用,而無需操心將數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上或者解析響應(yīng)之類的問題冲泥。所以才有了如下的網(wǎng)絡(luò)模型:在客戶端為遠(yuǎn)程對象安裝一個(gè)代理驹碍。代理是位于客戶端虛擬機(jī)中的一個(gè)對象壁涎,它對于客戶端程序來說,就像是要訪問的遠(yuǎn)程對象一樣志秃≌颍客戶端調(diào)用此代理時(shí),只需進(jìn)行常規(guī)的方法調(diào)用浮还。而客戶端代理則負(fù)責(zé)使用網(wǎng)絡(luò)協(xié)議與服務(wù)器進(jìn)行聯(lián)系竟坛。

<center style="color: rgb(51, 51, 51); font-family: "Microsoft Yahei"; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">
遠(yuǎn)程方法調(diào)用RMI詳解,和RPC的思路很相似

</center>

現(xiàn)在的問題在于代理之間是如何進(jìn)行通信的?通常有三種方法:

1钧舌、CORBA:通過對象請求代理架構(gòu)担汤,支持任何編程語言編寫的對象之間的方法調(diào)用。

2洼冻、SOAP

3崭歧、RMI:JAVA的遠(yuǎn)程方法調(diào)用技術(shù),支持java的分布式對象之間的方法調(diào)用撞牢。

其中CORBA與SOAP都是完全獨(dú)立于言語的率碾,可以使用C、C++屋彪、JAVA來編寫所宰,而RMI只適用于JAVA。

RMI的工作原理

一畜挥、術(shù)語介紹

1仔粥、存根:當(dāng)客戶端要調(diào)用遠(yuǎn)程對象的一個(gè)方法時(shí),實(shí)際上調(diào)用的是代理對象上的一個(gè)普通方法蟹但,我們稱此代理對象為存根(stub)件炉。存根位于客戶端機(jī)器上,而非服務(wù)器上矮湘。

2斟冕、參數(shù)編組:存根會(huì)將遠(yuǎn)程方法所需的參數(shù)打包成一組字節(jié),對參數(shù)編碼的過程就稱為參數(shù)編組缅阳。參數(shù)編組的目的是將參數(shù)轉(zhuǎn)換成適合在虛擬機(jī)之間進(jìn)行傳遞的格式磕蛇,在RMI協(xié)議中,對象是使用序列化機(jī)制進(jìn)行編碼的十办。

二秀撇、編程模型

為了介紹RMI的編程模型,我下面會(huì)編寫一個(gè)DEMO向族。遠(yuǎn)程對象表示的是一個(gè)倉庫呵燕,而客戶端程序向倉庫詢問某個(gè)產(chǎn)品的價(jià)格。

1件相、接口定義

遠(yuǎn)程對象的能力是由在客戶端和服務(wù)器之間共享的接口所表示的:

<center style="color: rgb(51, 51, 51); font-family: "Microsoft Yahei"; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">
遠(yuǎn)程方法調(diào)用RMI詳解再扭,和RPC的思路很相似

</center>

遠(yuǎn)程對象的接口必須擴(kuò)展Remote接口氧苍,它位于java.rmi包中。接口中所有的方法必須聲明拋出RemoteException異常泛范。這是因?yàn)檫h(yuǎn)程方法總是存在失敗的可能让虐,所以java編程語言要求每一次遠(yuǎn)程方法的調(diào)用都必須捕獲RemoteException,并且指明當(dāng)調(diào)用不成功時(shí)應(yīng)執(zhí)行的相應(yīng)處理操作。

2罢荡、接口的實(shí)現(xiàn)

<center style="color: rgb(51, 51, 51); font-family: "Microsoft Yahei"; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">
遠(yuǎn)程方法調(diào)用RMI詳解赡突,和RPC的思路很相似

</center>

你可以看出這個(gè)類是遠(yuǎn)程方法調(diào)用的目標(biāo),因?yàn)樗鼣U(kuò)展自UnicastRemoteObject区赵,這個(gè)類的構(gòu)造器使得它的對象可供遠(yuǎn)程訪問惭缰。

3、RMI注冊表:通過JNDI發(fā)布RMI服務(wù)

  1. 要訪問服務(wù)器上的一個(gè)遠(yuǎn)程對象時(shí)笼才,客戶端必須先得到一個(gè)本地的存根對象漱受,也就是客戶端機(jī)器上的代理對象。那么問題來了患整,如何才能得到這個(gè)存根呢?
  2. 為此拜效,JDK提供了自舉注冊服務(wù)(bootstrap registry service)喷众,服務(wù)器程序應(yīng)該使用自舉注冊服務(wù)來注冊至少一個(gè)遠(yuǎn)程對象各谚。
  3. 而要注冊一個(gè)遠(yuǎn)程對象,需要一個(gè)RMI URL和一個(gè)對實(shí)現(xiàn)對象的引用到千。
  4. RMI 的URL以rmi:開頭昌渤,后接域名或IP地址(host),緊接著是端口號(hào)(port)憔四,***是服務(wù)名(service)膀息。

如:rmi://regserver.mycompany.cmo:99/central_warehouse

如果我們是在本地發(fā)布RMI服務(wù),那么host就是“l(fā)ocalhost”了赵,此外RMI默認(rèn)的端口號(hào)是“1099”潜支,當(dāng)然我們也可以自行設(shè)置,只要不與其他端口重復(fù)即可柿汛。 service實(shí)際上是基于同一個(gè)host與port下唯一的服務(wù)名冗酿。

發(fā)布RMI服務(wù):

<center style="color: rgb(51, 51, 51); font-family: "Microsoft Yahei"; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">
遠(yuǎn)程方法調(diào)用RMI詳解,和RPC的思路很相似

</center>

運(yùn)行結(jié)果:

<pre style="padding: 0px; margin: 0px 0px 1em; font-family: "Courier New", monospace; font-size: 12px; width: 643.5px; overflow: auto; background: rgb(230, 230, 230); color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

  1. Constructing server implementation
  2. Binding server implementation to registry
  3. Waiting for invocations from clients ...

</pre>

  1. 第20行只需提供一個(gè)port络断,就在JNDI中創(chuàng)建了一個(gè)注冊表裁替。
  2. 第21行通過bind方法綁定了RMI地址與RMI服務(wù)實(shí)現(xiàn)類。
  3. 執(zhí)行這個(gè)方法后貌笨,相當(dāng)于自動(dòng)發(fā)布了RMI服務(wù)弱判。接下來要做的事情就是寫一個(gè)RM客戶端調(diào)用已發(fā)布的RMI服務(wù)。

4锥惋、****調(diào)用RMI服務(wù)

<center style="color: rgb(51, 51, 51); font-family: "Microsoft Yahei"; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">
遠(yuǎn)程方法調(diào)用RMI詳解昌腰,和RPC的思路很相似

</center>

運(yùn)行結(jié)果:

<pre style="padding: 0px; margin: 0px 0px 1em; font-family: "Courier New", monospace; font-size: 12px; width: 643.5px; overflow: auto; background: rgb(230, 230, 230); color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">

  1. RMI registry binding:
  2. mate7:3700.0

</pre>

  1. 服務(wù)調(diào)用只需要知道兩個(gè)東西:1开伏、RMI請求路徑;2、RMI接口名
  2. 第15行剥哑,這里用的是接口名Warehouse,而不是實(shí)現(xiàn)類硅则。一定不能RMI接口的實(shí)現(xiàn)類,否則就是本地調(diào)用了株婴。
  3. 查看運(yùn)行結(jié)果怎虫,我們知道這次DEMO展示的遠(yuǎn)程調(diào)用成功了。

5困介、下面我們來看下RMI的網(wǎng)絡(luò)示意圖:

<center style="color: rgb(51, 51, 51); font-family: "Microsoft Yahei"; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">
遠(yuǎn)程方法調(diào)用RMI詳解大审,和RPC的思路很相似

</center>

  1. 借助JNDI這個(gè)所謂的命名與目錄服務(wù),我們成功地發(fā)布并調(diào)用了RMI服務(wù)座哩。實(shí)際上徒扶,JNDI就是一個(gè)注冊表,服務(wù)端將服務(wù)對象放入到注冊表中根穷,客戶端從注冊表中獲取服務(wù)對象姜骡。
  2. 在服務(wù)端我們發(fā)布了RMI服務(wù),并在JNDI中進(jìn)行了注冊屿良,此時(shí)就在服務(wù)端創(chuàng)建了一個(gè)Skeleton(骨架)圈澈,當(dāng)客戶端***次成功連接JNDI并獲取遠(yuǎn)程服務(wù)對象后,立馬在本地創(chuàng)建了一個(gè)Stub(存根)尘惧。
  3. 遠(yuǎn)程通信實(shí)際是通過Skeleton與Stub來完成的康栈,數(shù)據(jù)是基于TCP/IP協(xié)議,在“傳輸層”上發(fā)送的喷橙。
  4. 毋庸置疑啥么,理論上RMI一定比WebService要快,畢竟WebService是基于http協(xié)議的贰逾,而http所攜帶的數(shù)據(jù)是通過“應(yīng)用層”來傳輸?shù)男佟鬏攲虞^應(yīng)用層更為底層,越底層越快疙剑。

RMI的局限性

  1. 只能實(shí)現(xiàn)JAVA系統(tǒng)之間的調(diào)用氯迂,而WebService可以實(shí)現(xiàn)跨語言實(shí)現(xiàn)系統(tǒng)之間的調(diào)用。
  2. RMI使用了JAVA默認(rèn)的序列化方式核芽,對于性能要求比較高的系統(tǒng)囚戚,可能需要其他的序列化方案來解決。
  3. RMI服務(wù)在運(yùn)行時(shí)難免會(huì)存在故障轧简,例如驰坊,如果RMI服務(wù)無法連接了,就會(huì)導(dǎo)致客戶端無法響應(yīng)的現(xiàn)象哮独。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拳芙,一起剝皮案震驚了整個(gè)濱河市察藐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舟扎,老刑警劉巖分飞,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異睹限,居然都是意外死亡譬猫,警方通過查閱死者的電腦和手機(jī)涤躲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門陌宿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人奔坟,你說我怎么就攤上這事叨恨×危” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵痒钝,是天一觀的道長秉颗。 經(jīng)常有香客問我,道長送矩,這世上最難降的妖魔是什么蚕甥? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮益愈,結(jié)果婚禮上梢灭,老公的妹妹穿的比我還像新娘夷家。我一直安慰自己蒸其,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布库快。 她就那樣靜靜地躺著摸袁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪义屏。 梳的紋絲不亂的頭發(fā)上靠汁,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機(jī)與錄音闽铐,去河邊找鬼蝶怔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛兄墅,可吹牛的內(nèi)容都是我干的踢星。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼隙咸,長吁一口氣:“原來是場噩夢啊……” “哼沐悦!你這毒婦竟也來了成洗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤藏否,失蹤者是張志新(化名)和其女友劉穎瓶殃,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體副签,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡遥椿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了淆储。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片修壕。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖遏考,靈堂內(nèi)的尸體忽然破棺而出慈鸠,到底是詐尸還是另有隱情,我是刑警寧澤灌具,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布青团,位于F島的核電站,受9級特大地震影響咖楣,放射性物質(zhì)發(fā)生泄漏督笆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一诱贿、第九天 我趴在偏房一處隱蔽的房頂上張望娃肿。 院中可真熱鬧,春花似錦珠十、人聲如沸料扰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晒杈。三九已至,卻和暖如春孔厉,著一層夾襖步出監(jiān)牢的瞬間拯钻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工撰豺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粪般,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓污桦,卻偏偏與公主長得像亩歹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 在分布式服務(wù)框架中捆憎,一個(gè)最基礎(chǔ)的問題就是遠(yuǎn)程服務(wù)是怎么通訊的舅柜,在Java領(lǐng)域中有很多可實(shí)現(xiàn)遠(yuǎn)程通訊的技術(shù),例如:R...
    java菜閱讀 989評論 0 2
  • 代理模式——遠(yuǎn)程代理(Java RMI) @(設(shè)計(jì)模式) 一躲惰、遠(yuǎn)程代理——大使 在日常開發(fā)中致份,我們經(jīng)常會(huì)有本地服務(wù)...
    理查德成閱讀 5,548評論 0 7
  • RMI介紹 遠(yuǎn)程方法調(diào)用(RMI)顧名思義是一臺(tái)機(jī)器上的程序調(diào)用另一臺(tái)機(jī)器上的方法。這樣可以大致知道RMI是用來干...
    忘凈空閱讀 4,743評論 0 1
  • 面向?qū)ο缶幊蹋∣OP) Java是一個(gè)支持并發(fā)础拨、基于類和面向?qū)ο蟮挠?jì)算機(jī)編程語言氮块。下面列出了面向?qū)ο筌浖_發(fā)的優(yōu)點(diǎn)...
    大家請叫我小杰閱讀 1,131評論 0 0
  • JAVA面試題 1、作用域public,private,protected,以及不寫時(shí)的區(qū)別答:區(qū)別如下:作用域 ...
    JA尐白閱讀 1,154評論 1 0