分佈式服務架構之java遠程調用技術淺析

        在 分佈式服務框架中,一個最基礎的問題就是遠程服務是怎麼通信的,在Java領域中有不少可實現遠程通信的技術,例如:RMI、MINA、ESB、 Burlap、Hessian、SOAP、EJB和JMS等,這些名詞之間究竟是些什麼關係呢,它們背後究竟是基於什麼原理實現的呢,瞭解這些是實現分佈 式服務框架的基礎知識,而若是在性能上有高的要求的話,那深刻了解這些技術背後的機制就是必須的了,在這篇blog中咱們未來一探究竟,拋磚引玉,歡迎大 家提供更多的實現遠程通信的技術和原理的介紹。 php

基本原理 html

要實現網絡機器間的通信,首先得來看看計算機系統網絡通訊的基本 原理,在底層層面去看,網絡通訊須要作的就是將流從一臺計算機傳輸到另一臺計算機,基於傳輸協議和網絡IO來實現,其中傳輸協議比較出名的有http、 tcp、udp等等,http、tcp、udp都是在爲某類應用場景而定義出的傳輸協議,網絡IO,主要有bio、nio、aio三種方式,全部的分佈式 應用通信都基於這個原理而實現,只是爲了應用的易用,各類語言一般都會提供一些更爲貼近應用易用的應用層協議 java

應用級協議 web

遠程服務通信,須要達到的目標是在一臺計算機發起請求,另一臺 機器在接收到請求後進行相應的處理並將結果返回給請求端,這其中又會有諸如one way request、同步請求、異步請求等等請求方式,按照網絡通訊原理,須要實現這個須要作的就是將請求轉換成流,經過傳輸協議傳輸至遠端,遠端計算機在接 收到請求的流後進行處理,處理完畢後將結果轉化爲流,並經過傳輸協議返回給調用端。 spring

原理是這樣的,但爲了應用的方便,業界推出了不少基於此原理之上的應用級的協議,使得你們能夠不用去直接操做這麼底層的東西,一般應用級的遠程通訊協議會提供: 安全

一、爲了不直接作流操做這麼麻煩,提供一種更加易用或貼合語言的標準傳輸格式; 服務器

二、網絡通訊機制的實現,就是替你完成了將傳輸格式轉化爲流,經過某種傳輸協議傳輸至遠端計算機,遠端計算機在接收到流後轉化爲傳輸格式,並進行存儲或以某種方式通知遠端計算機。 網絡

因此在學習應用級的遠程通訊協議時,咱們能夠帶着這幾個問題進行學習: 架構

一、傳輸的標準格式是什麼? 併發

二、怎麼樣將請求轉化爲傳輸的流?

三、怎麼接收和處理流?

四、傳輸協議是?

不過應用級的遠程通訊協議並不會在傳輸協議上作什麼多大的改進, 主要是在流操做方面,讓應用層生成流和處理流的這個過程更加的貼合所使用的語言或標準,至於傳輸協議則一般都是可選的,在java領域中知名的 有:RMI、XML-RPC、Binary-RPC、SOAP、CORBA、JMS,來具體的看看這些遠程通訊的應用級協議:

RMI

RMI是個典型的爲java定製的遠程通訊協議,咱們都知道,在single vm中,咱們能夠經過直接調用java object instance來實現通訊,那麼在遠程通訊時,若是也能按照這種方式固然是最好了,這種遠程通訊的機制成爲RPC(Remote Procedure Call),RMI正是朝着這個目標而誕生的。

來看下基於RMI的一次完整的遠程通訊過程的原理:

一、客戶端發起請求,請求轉交至RMI客戶端的stub類;

二、stub類將請求的接口、方法、參數等信息進行序列化;

三、基於tcp/ip將序列化後的流傳輸至服務器端;

四、服務器端接收到流後轉發至相應的skelton類;

五、skelton類將請求的信息反序列化後調用實際的處理類;

六、處理類處理完畢後將結果返回給skelton類;

七、Skelton類將結果序列化,經過tcp/ip將流傳送給客戶端的stub;

八、stub在接收到流後反序列化,將反序列化後的Java Object返回給調用者。

來看jboss-remoting對於此過程的一個更好的圖示:

根據原理來回答下以前學習應用級協議帶着的幾個問題:

一、傳輸的標準格式是什麼?

是Java ObjectStream。

二、怎麼樣將請求轉化爲傳輸的流?

基於Java串行化機制將請求的java object信息轉化爲流。

三、怎麼接收和處理流?

根據採用的協議啓動相應的監聽端口,當有流進入後基於Java串行化機制將流進行反序列化,並根據RMI協議獲取到相應的處理對象信息,進行調用並處理,處理完畢後的結果一樣基於java串行化機制進行返回。

四、傳輸協議是?

tcp/ip。

XML-RPC

XML-RPC也是一種和RMI相似的遠程調用的協議,它和RMI的不一樣之處在於它以標準的xml格式來定義請求的信息(請求的對象、方法、參數等),這樣的好處是什麼呢,就是在跨語言通信的時候也可使用。

來看下XML-RPC協議的一次遠程通訊過程:

一、客戶端發起請求,按照XML-RPC協議將請求信息進行填充;

二、填充完畢後將xml轉化爲流,經過傳輸協議進行傳輸;

三、接收到在接收到流後轉換爲xml,按照XML-RPC協議獲取請求的信息並進行處理;

四、處理完畢後將結果按照XML-RPC協議寫入xml中並返回。

圖示以上過程:

一樣來回答問題:

一、傳輸的標準格式是?

標準格式的XML。

二、怎麼樣將請求轉化爲傳輸的流?

將XML轉化爲流。

三、怎麼接收和處理流?

經過監聽的端口獲取到請求的流,轉化爲XML,並根據協議獲取請求的信息,進行處理並將結果寫入XML中返回。

四、傳輸協議是?

Http。

Binary-RPC

Binary-RPC看名字就知道和XML-RPC是差很少的了,不一樣之處僅在於傳輸的標準格式由XML轉爲了二進制的格式。

一樣來回答問題:

一、傳輸的標準格式是?

標準格式的二進制文件。

二、怎麼樣將請求轉化爲傳輸的流?

將二進制格式文件轉化爲流。

三、怎麼接收和處理流?

經過監聽的端口獲取到請求的流,轉化爲二進制文件,根據協議獲取請求的信息,進行處理並將結果寫入XML中返回。

四、傳輸協議是?

Http。

SOAP

SOAP原意爲Simple Object Access Protocol,是一個用於分佈式環境的、輕量級的、基於XML進行信息交換的通訊協議,能夠認爲SOAP是XML RPC的高級版,二者的原理徹底相同,都是http+XML,不一樣的僅在於二者定義的XML規範不一樣,SOAP也是Webservice採用的服務調用協議標準,所以在此就很少加闡述了。

CORBA

Common Object Request Broker Architecture(公用對象請求代理[調度]程序體系結構),是一組用來定義「分佈式對象系統」的標準,由OMG(Object Menagement Group)做爲發起和標準制定單位。CORBA的目的是定義一套協議,符合這個協議的對象能夠互相交互,不論它們是用什麼樣的語言寫的,不論它們運行於什麼樣的機器和操做系統。

CORBA在我看來是個相似於SOA的體系架構,涵蓋可選的遠程通訊協議,但其自己不能列入通訊協議這裏來說,並且CORBA基本淘汰,再加上對CORBA也不怎麼懂,在此就不進行闡述了。

JMS

JMS呢,是實現java領域遠程通訊的一種手段和方法,基於 JMS實現遠程通訊時和RPC是不一樣的,雖然能夠作到RPC的效果,但由於不是從協議級別定義的,所以咱們不認爲JMS是個RPC協議,但它確實是個遠程 通訊協議,在其餘的語言體系中也存在着相似JMS的東西,能夠統一的將這類機制稱爲消息機制,而消息機制呢,一般是高併發、分佈式領域推薦的一種通訊機 制,這裏的主要一個問題是容錯(詳細見ErLang論文)。

來看JMS中的一次遠程通訊的過程:

一、客戶端將請求轉化爲符合JMS規定的Message;

二、經過JMS API將Message放入JMS Queue或Topic中;

三、如爲JMS Queue,則發送中相應的目標Queue中,如爲Topic,則發送給訂閱了此Topic的JMS Queue。

四、處理端則經過輪訓JMS Queue,來獲取消息,接收到消息後根據JMS協議來解析Message並處理。

回答問題:

一、傳輸的標準格式是?

JMS規定的Message。

二、怎麼樣將請求轉化爲傳輸的流?

將參數信息放入Message中便可。

三、怎麼接收和處理流?

輪訓JMS Queue來接收Message,接收到後進行處理,處理完畢後仍然是以Message的方式放入Queue中發送或Multicast。

四、傳輸協議是?

不限。

基於JMS也是經常使用的實現遠程異步調用的方法之一。

可選實現技術

固然,在上面的原理中並無介紹到全部的java領域可選的遠程通訊協議了,例如還有EJB採用的ORMI、Spring本身定義的一個簡單的Http Invoker等等。

看完原理後咱們再來看看目前java領域可用於實現遠程通信的框 架或library,知名的有:JBoss-Remoting、Spring-Remoting、Hessian、Burlap、 XFire(Axis)、ActiveMQ、Mina、Mule、EJB3等等,來對每種作個簡單的介紹和評價,其實呢,要作分佈式服務框架,這些東西都 是要有很是深入的瞭解的,由於分佈式服務框架實際上是包含了解決分佈式領域以及應用層面領域兩方面問題的。

固然,你也能夠本身根據遠程網絡通訊原理(transport protocol+Net IO)去實現本身的通信框架或library。

那麼在瞭解這些遠程通信的框架或library時,會帶着什麼問題去學習呢?

一、是基於什麼協議實現的?

二、怎麼發起請求?

三、怎麼將請求轉化爲符合協議的格式的?

四、使用什麼傳輸協議傳輸?

五、響應端基於什麼機制來接收請求?

六、怎麼將流還原爲傳輸格式的?

七、處理完畢後怎麼迴應?

JBoss-Remoting

Jboss-remoting是由jboss編寫的一個java領域的遠程通信框架,基於此框架,能夠很簡單的實現基於多種傳輸協議的java對象的RPC。

直接來回答問題:

一、是基於什麼協議實現的?

JBoss-Remoting是個通信框架,所以它支持多種協議方式的通訊,例如tcp/ip+io方式、rmi方式、http+io方式等。

二、怎麼發起請求?

在JBoss-Remoting中,只需將須要發起的請求參數對象傳入jboss-remoting的InvocationRequest對象便可,也可根據協議基於InvocationRequest封裝符合需求的InvocationRequest對象。

三、怎麼將請求轉化爲符合協議的格式的?

JBoss-Remoting基於Java串行化機制或JBoss本身的串行化實現來將請求轉化爲對象字節流。

四、使用什麼傳輸協議傳輸?

支持多種傳輸協議,例如tcp/ip、http等。

五、響應端基於什麼機制來接收請求?

響應端只需將本身的處理對象註冊到JBoss-Remoting提供的server端的Connector對象中便可。

六、怎麼將流還原爲傳輸格式的?

JBoss-Remoting基於java串行化機制或jboss本身的串行化實現來將請求信息還原爲java對象。

七、處理完畢後怎麼迴應?

處理完畢後將結果對象直接返回便可,jboss-remoting會將此對象按照協議進行序列化,返回至調用端。

另外,jboss-remoting支持多種通訊方式,例如同步/異步/單向通訊等。

Spring-Remoting

Spring-remoting是Spring提供java領域的遠程通信框架,基於此框架,一樣也能夠很簡單的將普通的spring bean以某種遠程協議的方式來發布,一樣也能夠配置spring bean爲遠程調用的bean。

一、是基於什麼協議實現的?

和JBoss-Remoting同樣,做爲一個遠程通信的框架,Spring經過集成多種遠程通信的library,從而實現了對多種協議的支持,例如rmi、http+io、xml-rpc、binary-rpc等。

二、怎麼發起請求?

在Spring中,因爲其對於遠程調用的bean採用的是proxy實現,發起請求徹底是經過服務接口調用的方式。

三、怎麼將請求轉化爲符合協議的格式的?

Spring按照協議方式將請求的對象信息轉化爲流,例如Spring Http Invoker是基於Spring本身定義的一個協議來實現的,傳輸協議上採用的爲http,請求信息是基於java串行化機制轉化爲流進行傳輸。

四、使用什麼傳輸協議傳輸?

支持多種傳輸協議,例如rmi、http等等。

五、響應端基於什麼機制來接收請求?

響應端遵循協議方式來接收請求,對於使用者而言,則只需經過spring的配置方式將普通的spring bean配置爲響應端或者說提供服務端。

六、怎麼將流還原爲傳輸格式的?

按照協議方式來進行還原。

七、處理完畢後怎麼迴應?

處理完畢後直接返回便可,spring-remoting將根據協議方式來作相應的序列化。

Hessian

Hessian是由caucho提供的一個基於binary-RPC實現的遠程通信library。

一、是基於什麼協議實現的?

基於Binary-RPC協議實現。

二、怎麼發起請求?

需經過Hessian自己提供的API來發起請求。

三、怎麼將請求轉化爲符合協議的格式的?

Hessian經過其自定義的串行化機制將請求信息進行序列化,產生二進制流。

四、使用什麼傳輸協議傳輸?

Hessian基於Http協議進行傳輸。

五、響應端基於什麼機制來接收請求?

響應端根據Hessian提供的API來接收請求。

六、怎麼將流還原爲傳輸格式的?

Hessian根據其私有的串行化機制來將請求信息進行反序列化,傳遞給使用者時已經是相應的請求信息對象了。

七、處理完畢後怎麼迴應?

處理完畢後直接返回,hessian將結果對象進行序列化,傳輸至調用端。

Burlap

Burlap也是有caucho提供,它和hessian的不一樣在於,它是基於XML-RPC協議的。

一、是基於什麼協議實現的?

基於XML-RPC協議實現。

二、怎麼發起請求?

根據Burlap提供的API。

三、怎麼將請求轉化爲符合協議的格式的?

將請求信息轉化爲符合協議的XML格式,轉化爲流進行傳輸。

四、使用什麼傳輸協議傳輸?

Http協議。

五、響應端基於什麼機制來接收請求?

監聽Http請求。

六、怎麼將流還原爲傳輸格式的?

根據XML-RPC協議進行還原。

七、處理完畢後怎麼迴應?

返回結果寫入XML中,由Burlap返回至調用端。

XFire、Axis

XFire、Axis是Webservice的實現框架,WebService可算是一個完整的SOA架構實現標準了,所以採用XFire、Axis這些也就意味着是採用webservice方式了。

一、是基於什麼協議實現的?

基於SOAP協議。

二、怎麼發起請求?

獲取到遠端service的proxy後直接調用。

三、怎麼將請求轉化爲符合協議的格式的?

將請求信息轉化爲遵循SOAP協議的XML格式,由框架轉化爲流進行傳輸。

四、使用什麼傳輸協議傳輸?

Http協議。

五、響應端基於什麼機制來接收請求?

監聽Http請求。

六、怎麼將流還原爲傳輸格式的?

根據SOAP協議進行還原。

七、處理完畢後怎麼迴應?

返回結果寫入XML中,由框架返回至調用端。

ActiveMQ

ActiveMQ是JMS的實現,基於JMS這類消息機制實現遠程通信是一種不錯的選擇,畢竟消息機制自己的功能使得基於它能夠很容易的去實現同步/異步/單向調用等,並且消息機制從容錯角度上來講也是個不錯的選擇,這是Erlang可以作到容錯的重要基礎。

一、是基於什麼協議實現的?

基於JMS協議。

二、怎麼發起請求?

遵循JMS API發起請求。

三、怎麼將請求轉化爲符合協議的格式的?

不太清楚,猜測應該是二進制流。

四、使用什麼傳輸協議傳輸?

支持多種傳輸協議,例如tcp/ip、udp、http等等。

五、響應端基於什麼機制來接收請求?

監聽符合協議的端口。

六、怎麼將流還原爲傳輸格式的?

同問題3。

七、處理完畢後怎麼迴應?

遵循JMS API生成消息,並寫入JMS Queue中。

基於JMS此類機制實現遠程通信的例子有Spring-Intergration、Mule、Lingo等等。

Mina

Mina是Apache提供的通信框架,在以前一直沒有提到網絡 IO這塊,以前說起的框架或library基本都是基於BIO的,而Mina是採用NIO的,NIO在併發量增加時對比BIO而言會有明顯的性能提高,而 java性能的提高,與其NIO這塊與OS的緊密結合是有不小的關係的。

一、是基於什麼協議實現的?

可選的傳輸協議+NIO。

二、怎麼發起請求?

經過Mina提供的Client API。

三、怎麼將請求轉化爲符合協議的格式的?

Mina遵循java串行化機制對請求對象進行序列化。

四、使用什麼傳輸協議傳輸?

支持多種傳輸協議,例如tcp/ip、http等等。

五、響應端基於什麼機制來接收請求?

以NIO的方式監聽協議端口。

六、怎麼將流還原爲傳輸格式的?

遵循java串行化機制對請求對象進行反序列化。

七、處理完畢後怎麼迴應?

遵循Mina API進行返回。

MINA是NIO方式的,所以支持異步調用是毫無懸念的。

EJB

EJB最突出的在於其分佈式,EJB採用的是ORMI協議,和RMI協議是差很少的,但EJB在分佈式通信的安全控制、transport pool、smart proxy等方面的突出使得其在分佈式領域是不可忽視的力量。

一、是基於什麼協議實現的?

基於ORMI協議。

二、怎麼發起請求?

EJB調用。

三、怎麼將請求轉化爲符合協議的格式的?

遵循java串行化機制對請求對象進行序列化。

四、使用什麼傳輸協議傳輸?

tcp/ip。

五、響應端基於什麼機制來接收請求?

監聽協議端口。

六、怎麼將流還原爲傳輸格式的?

遵循java串行化機制對請求對象進行反序列化。

七、處理完畢後怎麼迴應?

直接返回處理對象便可。

在以前的分佈式服務框架系列的文章中對於jndi有誤導的嫌疑,在這篇blog中也順帶的提下jndi的機制,因爲JNDI取決於具體的實現,在這裏只能是講解下jboss的jndi的實現了。

在將對象實例綁定到jboss jnp server後,當遠程端採用context.lookup()方式獲取遠程對象實例並開始調用時,jboss jndi的實現方法是從jnp server上獲取對象實例,將其序列化回本地,而後在本地進行反序列化,以後在本地進行類調用。

經過這個機制,就能夠知道了,本地實際上是必須有綁定到jboss上的對象實例的class的,不然反序列化的時候確定就失敗了,而遠程通信須要作到的是在遠程執行某動做,並獲取到相應的結果,可見純粹基於JNDI是沒法實現遠程通信的。

但JNDI也是實現分佈式服務框架一個很關鍵的技術點,由於能夠經過它來實現透明化的遠端和本地調用,就像ejb,另外它也是個很好的隱藏實際部署機制(就像datasource)等的方案。

總結

由上一系列的分析可知,在遠程通信領域中,涉及的知識點仍是至關 的多的,例若有:通訊協議或遠程調用協議(tcp/http/udp/rmi/xml-rpc etc.)、消息機制、網絡IO(BIO/NIO/AIO)、MultiThread、本地調用與遠程調用的透明化方案(涉及java classloader、Dynamic Proxy、Unit Test etc.)、異步與同步調用、網絡通訊處理機制(自動重連、廣播、異常、池處理等等)、Java Serialization (各類協議的私有序列化機制等)、各類框架的實現原理(傳輸格式、如何將傳輸格式轉化爲流的、如何將請求信息轉化爲傳輸格式的、如何接收流的、如何將流還 原爲傳輸格式的等等),要精通其中的哪些東西,得根據實際需求來決定了,只有在瞭解了原理的狀況下才能很容易的作出選擇,甚至能夠根據需求作私有的遠程通 訊協議,對於從事分佈式服務平臺或開發較大型的分佈式應用的人而言,我以爲至少上面說起的知識點是須要比較瞭解的。

參考文檔(感謝這些文章)

RMI原理及實現:http://www.yesky.com/274/1625274.shtml

Java NIO原理和使用:http://www.jdon.com/concurrent/nio%D4%AD%C0%ED%D3%A6%D3%C3.htm

XML RPC協議:http://hedong.3322.org/archives/000470.html

http://www.mengyan.org/blog/archives/2005/07/12/30.html

Spring技術應用中的遠程服務詳解:http://www.builder.com.cn/2007/1027/583384.shtml

JAVA RPC通訊機制之SOAP:http://www.java114.com/content16/content3826.html

Java Remoting:Protocol BenchMarks:http://q.sohu.com/forum/5/topic/1148909

Evalution of RMI Alternative:https://www.jfire.org/modules/phpwiki/index.php/Evaluation%20of%20RMI%20Alternative

Metaprotocol Taxonomy:http://hessian.caucho.com/doc/metaprotocol-taxonomy.xtp

什麼是Webservice:http://www.vchome.net/dotnet/webservice/webservice15.htm

相關文章
相關標籤/搜索