Java远程通讯技术及原理分析
? ? ? ?在分布式服務框架中,一個最基礎的問題就是遠程服務是怎么通訊的,在Java領域中有很多可實現遠程通訊的技術,例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,這些名詞之間到底是些什么關系呢,它們背后到底是基于什么原理實現的呢,了解這些是實現分布式服務框架的基礎知識,而如果在性能上有高的要求的話,那深入了解這些技術背后的機制就是必須的了。
一、基本原理
? ? ? ?要實現網絡機器間的通訊,首先得來看看計算機系統網絡通信的基本原理,在底層層面去看,網絡通信需要做的就是將流從一臺計算機傳輸到另外一臺計算機,基于傳輸協議和網絡IO來實現,其中傳輸協議比較出名的有tcp、udp等等,tcp、udp都是在基于Socket概念上為某類應用場景而擴展出的傳輸協議,網絡IO主要有bio、nio、aio三種方式,所有的分布式應用通訊都基于這個原理而實現,只是為了應用的易用,各種語言通常都會提供一些更為貼近應用易用的應用層協議。
二、消息模式
? ? ? ?歸根結底,企業應用系統就是對數據的處理,而對于一個擁有多個子系統的企業應用系統而言,它的基礎支撐無疑就是對消息的處理。與對象不同,消息本質上是一種數據結構(當然,對象也可以看做是一種特殊的消息),它包含消費者與服務雙方都能識別的數據,這些數據需要在不同的進程(機器)之間進行傳遞,并可能會被多個完全不同的客戶端消費。消息傳遞相較文件傳遞與遠程過程調用(RPC)而言,似乎更勝一籌,因為它具有更好的平臺無關性,并能夠很好地支持并發與異步調用。
? ? ? ?對于Web Service與Restful而言,則可以看做是消息傳遞技術的一種衍生或封裝。
2.1、消息通道(Message Channel)模式
? ? ? ?我們常常運用的消息模式是Message Channel(消息通道)模式,如圖所示。
? ? ? ?消息通道作為在客戶端(消費者,Consumer)與服務(生產者,Producer)之間引入的間接層,可以有效地解除二者之間的耦合。只要實現規定雙方需要通信的消息格式,以及處理消息的機制與時機,就可以做到消費者對生產者的“無知”。事實上,該模式可以支持多個生產者與消費者。例如,我們可以讓多個生產者向消息通道發送消息,因為消費者對生產者的無知性,它不必考慮究竟是哪個生產者發來的消息。
? ? ? ?雖然消息通道解除了生產者與消費者之間的耦合,使得我們可以任意地對生產者與消費者進行擴展,但它又同時引入了各自對消息通道的依賴,因為它們必須知道通道資源的位置。要解除這種對通道的依賴,可以考慮引入Lookup服務來查找該通道資源。例如,在JMS中就可以通過JNDI來獲取消息通道Queue。若要做到充分的靈活性,可以將與通道相關的信息存儲到配置文件中,Lookup服務首先通過讀取配置文件來獲得通道。
? ? ? ?消息通道通常以隊列的形式存在,這種先進先出的數據結構無疑最為適合這種處理消息的場景。微軟的MSMQ、IBM MQ、JBoss MQ以及開源的RabbitMQ、Apache ActiveMQ都通過隊列實現了Message Channel模式。因此,在選擇運用Message Channel模式時,更多地是要從質量屬性的層面對各種實現了該模式的產品進行全方位的分析與權衡。例如,消息通道對并發的支持以及在性能上的表現;消息通道是否充分地考慮了錯誤處理;對消息安全的支持;以及關于消息持久化、災備(fail over)與集群等方面的支持。
? ? ? ?因為通道傳遞的消息往往是一些重要的業務數據,一旦通道成為故障點或安全性的突破點,對系統就會造成災難性的影響。
此處也順帶的提下jndi的機制,由于JNDI取決于具體的實現,在這里只能是講解下jboss的jndi的實現了:
? ? ? ?在將對象實例綁定到jboss jnp server后,當遠程端采用context.lookup()方式獲取遠程對象實例并開始調用時,jboss jndi的實現方法是從jnp server上獲取對象實例,將其序列化回本地,然后在本地進行反序列化,之后在本地進行類調用。
? ? ? ?通過這個機制,就可以知道了,本地其實是必須有綁定到jboss上的對象實例的class的,否則反序列化的時候肯定就失敗了,而遠程通訊需要做到的是在遠程執行某動作,并獲取到相應的結果,可見純粹基于JNDI是無法實現遠程通訊的。
? ? ? ?但JNDI也是實現分布式服務框架一個很關鍵的技術點,因為可以通過它來實現透明化的遠端和本地調用,就像ejb,另外它也是個很好的隱藏實際部署機制(就像datasource)等的方案。
2.2、發布者-訂閱者(Publisher-Subscriber)模式
? ? ? ?一旦消息通道需要支持多個消費者時,就可能面臨兩種模型的選擇:拉模型與推模型。拉模型是由消息的消費者發起的,主動權把握在消費者手中,它會根據自己的情況對生產者發起調用。如圖所示:
? ? ? ?拉模型的另一種體現則由生產者在狀態發生變更時,通知消費者其狀態發生了改變。但得到通知的消費者卻會以回調方式,通過調用傳遞過來的消費者對象獲取更多細節消息。
? ? ? ?在基于消息的分布式系統中,拉模型的消費者通常以Batch Job的形式,根據事先設定的時間間隔,定期偵聽通道的情況。一旦發現有消息傳遞進來,就會轉而將消息傳遞給真正的處理器(也可以看做是消費者)處理消息,執行相關的業務。
? ? ? ?推模型的主動權常常掌握在生產者手中,消費者被動地等待生產者發出的通知,這就要求生產者必須了解消費者的相關信息。如圖所示:
? ? ? ?對于推模型而言,消費者無需了解生產者。在生產者通知消費者時,傳遞的往往是消息(或事件),而非生產者自身。同時,生產者還可以根據不同的情況,注冊不同的消費者,又或者在封裝的通知邏輯中,根據不同的狀態變化,通知不同的消費者。
? ? ? ?兩種模型各有優勢。拉模型的好處在于可以進一步解除消費者對通道的依賴,通過后臺任務去定期訪問消息通道。壞處是需要引入一個單獨的服務進程,以Schedule形式執行。而對于推模型而言,消息通道事實上會作為消費者觀察的主體,一旦發現消息進入,就會通知消費者執行對消息的處理。無論推模型,拉模型,對于消息對象而言,都可能采用類似Observer模式的機制,實現消費者對生產者的訂閱,因此這種機制通常又被稱為Publisher-Subscriber模式,如圖所示:
? ? ? ?通常情況下,發布者和訂閱者都會被注冊到用于傳播變更的基礎設施(即消息通道)上。發布者會主動地了解消息通道,使其能夠將消息發送到通道中;消息通道一旦接收到消息,會主動地調用注冊在通道中的訂閱者,進而完成對消息內容的消費。
? ? ? ?對于訂閱者而言,有兩種處理消息的方式。一種方式是廣播機制,這時消息通道中的消息在出列的同時,還需要復制消息對象,將消息傳遞給多個訂閱者。例如,有多個子系統都需要獲取從CRM系統傳來的客戶信息,并根據傳遞過來的客戶信息,進行相應的處理。此時的消息通道又被稱為Propagation通道。另一種方式則屬于搶占機制,它遵循同步方式,在同一時間只能有一個訂閱者能夠處理該消息。實現Publisher-Subscriber模式的消息通道會選擇當前空閑的唯一訂閱者,并將消息出列,并傳遞給訂閱者的消息處理方法。
? ? ? ?目前,有許多消息中間件都能夠很好地支持Publisher-Subscriber模式,例如JMS接口規約中對于Topic對象提供的MessagePublisher與MessageSubscriber接口。RabbitMQ也提供了自己對該模式的實現。微軟的MSMQ雖然引入了事件機制,可以在隊列收到消息時觸發事件,通知訂閱者。但它并非嚴格意義上的Publisher-Subscriber模式實現。由微軟MVP Udi Dahan作為主要貢獻者的NServiceBus,則對MSMQ以及WCF做了進一層包裝,并能夠很好地實現這一模式。
2.3、消息路由(Message Router)模式
? ? ? ?無論是Message Channel模式,還是Publisher-Subscriber模式,隊列在其中都扮演了舉足輕重的角色。然而,在企業應用系統中,當系統變得越來越復雜時,對性能的要求也會越來越高,此時對于系統而言,可能就需要支持同時部署多個隊列,并可能要求分布式部署不同的隊列。這些隊列可以根據定義接收不同的消息,例如訂單處理的消息,日志信息,查詢任務消息等。這時,對于消息的生產者和消費者而言,并不適宜承擔決定消息傳遞路徑的職責。事實上,根據S單一職責原則,這種職責分配也是不合理的,它既不利于業務邏輯的重用,也會造成生產者、消費者與消息隊列之間的耦合,從而影響系統的擴展。
既然這三種對象(組件)都不宜承擔這樣的職責,就有必要引入一個新的對象專門負責傳遞路徑選擇的功能,這就是所謂的Message Router模式,如圖所示:
? ? ? ?通過消息路由,我們可以配置路由規則指定消息傳遞的路徑,以及指定具體的消費者消費對應的生產者。例如指定路由的關鍵字,并由它來綁定具體的隊列與指定的生產者(或消費者)。路由的支持提供了消息傳遞與處理的靈活性,也有利于提高整個系統的消息處理能力。同時,路由對象有效地封裝了尋找與匹配消息路徑的邏輯,就好似一個調停者(Meditator),負責協調消息、隊列與路徑尋址之間關系。
三、應用級協議
? ? ? ?遠程服務通訊,需要達到的目標是在一臺計算機發起請求,另外一臺機器在接收到請求后進行相應的處理并將結果返回給請求端,這其中又會有諸如one way request、同步請求、異步請求等等請求方式,按照網絡通信原理,需要實現這個需要做的就是將請求轉換成流,通過傳輸協議傳輸至遠端,遠端計算機在接收到請求的流后進行處理,處理完畢后將結果轉化為流,并通過傳輸協議返回給調用端。
? ? ? ?原理是這樣的,但為了應用的方便,業界推出了很多基于此原理之上的應用級的協議,使得大家可以不用去直接操作這么底層的東西,通常應用級的遠程通信協議會提供:
(1)、為了避免直接做流操作這么麻煩,提供一種更加易用或貼合語言的標準傳輸格式;
(2)、網絡通信機制的實現,就是替你完成了將傳輸格式轉化為流,通過某種傳輸協議傳輸至遠端計算機,遠端計算機在接收到流后轉化為傳輸格式,并進行存儲或以某種方式通知遠端計算機。
所以在學習應用級的遠程通信協議時,我們可以帶著這幾個問題進行學習:
(1)、傳輸的標準格式是什么?
(2)、怎么樣將請求轉化為傳輸的流?
(3)、怎么接收和處理流?
(4)、傳輸協議是?
? ? ? ?不過應用級的遠程通信協議并不會在傳輸協議上做什么多大的改進,主要是在流操作方面,讓應用層生成流和處理流的這個過程更加的貼合所使用的語言或標準,至于傳輸協議則通常都是可選的,在java領域中知名的有:RMI、XML-RPC、Binary-RPC、SOAP、CORBA、JMS、HTTP,來具體的看看這些遠程通信的應用級協議。
3.1、RMI(遠程方法調用)
? ? ? ?RMI是個典型的為java定制的遠程通信協議,我們都知道,在single vm中,我們可以通過直接調用java object instance來實現通信,那么在遠程通信時,如果也能按照這種方式當然是最好了,這種遠程通信的機制成為RPC(Remote Procedure Call),RMI正是朝著這個目標而誕生的。
? ? ? ?RMI 采用stubs 和 skeletons 來進行遠程對象(remote object)的通訊。stub 充當遠程對象的客戶端代理,有著和遠程對象相同的遠程接口,遠程對象的調用實際是通過調用該對象的客戶端代理對象stub來完成的,通過該機制RMI就好比它是本地工作,采用tcp/ip協議,客戶端直接調用服務端上的一些方法。優點是強類型,編譯期可檢查錯誤;缺點是只能基于JAVA語言,客戶機與服務器緊耦合。
來看下基于RMI的一次完整的遠程通信過程的原理:
(1)、客戶端發起請求,請求轉交至RMI客戶端的stub類;
(2)、stub類將請求的接口、方法、參數等信息進行序列化;
(3)、基于socket將序列化后的流傳輸至服務器端;
(4)、服務器端接收到流后轉發至相應的skeleton類;
(5)、skeleton類將請求的信息反序列化后調用實際的處理類;
(6)、處理類處理完畢后將結果返回給skelton類;
(7)、skeleton類將結果序列化,通過socket將流傳送給客戶端的stub;
(8)、stub在接收到流后反序列化,將反序列化后的Java Object返回給調用者。
根據原理來回答下之前學習應用級協議帶著的幾個問題:
(1)、傳輸的標準格式是什么?
是Java ObjectStream。
(2)、怎么樣將請求轉化為傳輸的流?
基于Java串行化機制將請求的java object信息轉化為流。
(3)、怎么接收和處理流?
根據采用的協議啟動相應的監聽端口,當有流進入后基于Java串行化機制將流進行反序列化,并根據RMI協議獲取到相應的處理對象信息,進行調用并處理,處理完畢后的結果同樣基于java串行化機制進行返回。
(4)、傳輸協議是?
Socket。
3.2、XML-RPC
? ? ? ?RPC使用C/S方式,采用http協議,發送請求到服務器,等待服務器返回結果。這個請求包括一個參數集和一個文本集,通常形成“classname.methodname”形式。優點是跨語言跨平臺,C端、S端有更大的獨立性,缺點是不支持對象,無法在編譯器檢查錯誤,只能在運行期檢查。
? ? ? ?XML-RPC也是一種和RMI類似的遠程調用的協議,它和RMI的不同之處在于它以標準的xml格式來定義請求的信息(請求的對象、方法、參數等),這樣的好處是什么呢,就是在跨語言通訊的時候也可以使用。
來看下XML-RPC協議的一次遠程通信過程:
(1)、客戶端發起請求,按照XML-RPC協議將請求信息進行填充;
(2)、填充完畢后將xml轉化為流,通過傳輸協議進行傳輸;
(3)、接收到在接收到流后轉換為xml,按照XML-RPC協議獲取請求的信息并進行處理;
(4)、處理完畢后將結果按照XML-RPC協議寫入xml中并返回。
同樣來回答問題:
(1)、傳輸的標準格式是?
標準格式的XML。
(2)、怎么樣將請求轉化為傳輸的流?
將XML轉化為流。
(3)、怎么接收和處理流?
通過監聽的端口獲取到請求的流,轉化為XML,并根據協議獲取請求的信息,進行處理并將結果寫入XML中返回。
(4)、傳輸協議是?
Http。
3.3、Binary-RPC
Binary-RPC看名字就知道和XML-RPC是差不多的了,不同之處僅在于傳輸的標準格式由XML轉為了二進制的格式。
同樣來回答問題:
(1)、傳輸的標準格式是?
標準格式的二進制文件。
(2)、怎么樣將請求轉化為傳輸的流?
將二進制格式文件轉化為流。
(3)、怎么接收和處理流?
通過監聽的端口獲取到請求的流,轉化為二進制文件,根據協議獲取請求的信息,進行處理并將結果寫入XML中返回。
(4)、傳輸協議是?
Http。
3.4、SOAP
? ? ? ?SOAP原意為Simple Object Access Protocol,是一個用于分布式環境的、輕量級的、基于XML進行信息交換的通信協議,可以認為SOAP是XML RPC的高級版,兩者的原理完全相同,都是http+XML,不同的僅在于兩者定義的XML規范不同,SOAP也是Webservice采用的服務調用協議標準,因此在此就不多加闡述了。
? ? ? ?Web Service提供的服務是基于web容器的,底層使用http協議,類似一個遠程的服務提供者,比如天氣預報服務,對各地客戶端提供天氣預報,是一種請求應答的機制,是跨系統跨平臺的。就是通過一個servlet,提供服務出去。
? ? ? ?首先客戶端從服務器獲得WebService的WSDL,同時在客戶端生成一個代理類(Proxy Class),這個代理類負責與WebService服務器進行Request和Response。當一個數據(XML格式的)被封裝成SOAP格式的數據流發送到服務器端的時候,就會生成一個進程對象并且把接收到這個Request的SOAP包進行解析,然后對事物進行處理,處理結束以后再對這個計算結果進行SOAP包裝,然后把這個包作為一個Response發送給客戶端的代理類(Proxy Class),同樣地,這個代理類也對這個SOAP包進行解析處理,繼而進行后續操作。這就是WebService的一個運行過程。
Web Service大體上分為5個層次:
(1)、Http傳輸信道;
(2)、XML的數據格式;
(3)、SOAP封裝格式;
(4)、WSDL的描述方式;
(5)、UDDI UDDI是一種目錄服務,企業可以使用它對Webservices進行注冊和搜索;
3.5、JMS
? ? ? ?JMS是實現java領域遠程通信的一種手段和方法,基于JMS實現遠程通信時和RPC是不同的,雖然可以做到RPC的效果,但因為不是從協議級別定義的,因此我們不認為JMS是個RPC協議,但它確實是個遠程通信協議,在其他的語言體系中也存在著類似JMS的東西,可以統一的將這類機制稱為消息機制,而消息機制呢,通常是高并發、分布式領域推薦的一種通信機制,這里的主要一個問題是容錯。
? ? ? ?JMS是Java的消息服務,JMS的客戶端之間可以通過JMS服務進行異步的消息傳輸。JMS支持兩種消息模型:Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub),即點對點和發布訂閱模型。
來看JMS中的一次遠程通信的過程:
(1)、客戶端將請求轉化為符合JMS規定的Message;
(2)、通過JMS API將Message放入JMS Queue或Topic中;
(3)、如為JMS Queue,則發送中相應的目標Queue中,如為Topic,則發送給訂閱了此Topic的JMS Queue。
(4)、處理端則通過輪訓JMS Queue,來獲取消息,接收到消息后根據JMS協議來解析Message并處理。
同樣來回答問題:
(1)、傳輸的標準格式是?
JMS規定的Message。
(2)、怎么樣將請求轉化為傳輸的流?
將參數信息放入Message中即可。
(3)、怎么接收和處理流?
輪訓JMS Queue來接收Message,接收到后進行處理,處理完畢后仍然是以Message的方式放入Queue中發送或Multicast。
(4)、傳輸協議是?
不限。
基于JMS也是常用的實現遠程異步調用的方法之一。
四、之間的區別
4.1、RPC與RMI
(1)、RPC跨語言,而RMI只支持Java。
(2)、RMI調用遠程對象方法,允許方法返回Java對象以及基本數據類型,而RPC不支持對象的概念,傳送到RPC服務的消息由外部數據表示 (External Data Representation, XDR) 語言表示,這種語言抽象了字節序類和數據類型結構之間的差異。 只有由 XDR 定義的數據類型才能被傳遞,可以說 RMI 是面向對象方式的Java RPC。
(3)、在方法調用上,RMI中,遠程接口使每個遠程方法都具有方法簽名。如果一個方法在服務器上執行,但是沒有相匹配的簽名被添加到這個遠程接口上,那么這個新方法就不能被RMI客戶方所調用。
? ? ?在RPC中,當一個請求到達RPC服務器時,這個請求就包含了一個參數集和一個文本值,通常形成“classname.methodname”的形式。這就向RPC服務器表明,被請求的方法在為 “classname”的類中,名叫“methodname”。然后RPC服務器就去搜索與之相匹配的類和方法,并把它作為那種方法參數類型的輸入。這里的參數類型是與RPC請求中的類型是匹配的。一旦匹配成功,這個方法就被調用了,其結果被編碼后返回客戶方。
(4)、RPC本身沒有規范,但基本的工作機制是一樣的,即:serialization/deserialization+stub+skeleton,寬泛的講,只要能實現遠程調用,都是RPC,如:rmi .net-remoting ws/soap/rest hessian xmlrpc thrift potocolbuffer。
(5)、在Java里提供了完整的sockets通訊接口,但sockets要求客戶端和服務端必須進行應用級協議的編碼交換數據,采用sockets是非常麻煩的。一個代替Sockets的協議是RPC(Remote Procedure Call), 它抽象出了通訊接口用于過程調用,使得編程者調用一個遠程過程和調用本地過程同樣方便。
RPC 系統采用XDR來編碼遠程調用的參數和返回值。但RPC并不支持對象,所以,面向對象的遠程調用RMI(Remote Method Invocation)成為必然選擇。采用RMI,調用遠程對象和調用本地對象同樣方便。RMI 采用JRMP(Java Remote Method Protocol)通訊協議,是構建在TCP/IP協議上的一種遠程調用方法。
4.2 JMS與RMI
? ? ? ?采用JMS服務,對象是在物理上被異步從網絡的某個JVM 上直接移動到另一個JVM 上(是消息通知機制),而RMI對象是綁定在本地JVM 中,只有函數參數和返回值是通過網絡傳送的(是請求應答機制)。
? ? ? ?RMI一般都是同步的,也就是說,當client調用Server的一個方法的時候,需要等到對方的返回,才能繼續執行client端,這個過程調用本地方法感覺上是一樣的,這也是RMI的一個特點。
? ? ? ?JMS 一般只是一個點發出一個Message到Message Server,發出之后一般不會關心誰用了這個message。
所以,一般RMI的應用是緊耦合,JMS的應用相對來說是松散耦合應用。
4.3 Webservice與RMI
? ? ? ?RMI是在tcp協議上傳遞可序列化的java對象,只能用在java虛擬機上,綁定語言,客戶端和服務端都必須是java。webservice沒有這個限制,webservice是在http協議上傳遞xml文本文件,與語言和平臺無關。
4.4 Webservice與JMS
? ? ? ?Webservice專注于遠程服務調用,jms專注于信息交換。
? ? ? ?大多數情況下Webservice是兩系統間的直接交互(Consumer <--> Producer),而大多數情況下jms是三方系統交互(Consumer <- Broker -> Producer)。當然,JMS也可以實現request-response模式的通信,只要Consumer或Producer其中一方兼任broker即可。
? ? ? ?JMS可以做到異步調用完全隔離了客戶端和服務提供者,能夠抵御流量洪峰;WebService服務通常為同步調用,需要有復雜的對象轉換,相比SOAP,現在JSON,rest都是很好的http架構方案;
? ? ? ?JMS是java平臺上的消息規范。一般jms消息不是一個xml,而是一個java對象,很明顯,jms沒考慮異構系統,說白了,JMS就沒考慮非java的東西。但是好在現在大多數的jms provider(就是JMS的各種實現產品)都解決了異構問題。相比WebService的跨平臺各有千秋吧。
五、可選實現技術
? ? ? ?目前java領域可用于實現遠程通訊的框架或library,知名的有:JBoss-Remoting、Spring-Remoting、Hessian、Burlap、XFire(Axis)、ActiveMQ、Mina、Mule、EJB3等等,來對每種做個簡單的介紹和評價,其實呢,要做分布式服務框架,這些東西都是要有非常深刻的了解的,因為分布式服務框架其實是包含了解決分布式領域以及應用層面領域兩方面問題的。
? ? ? ?當然,你也可以自己根據遠程網絡通信原理(transport protocol+Net IO)去實現自己的通訊框架或library。
? ? ? ?那么在了解這些遠程通訊的框架或library時,會帶著什么問題去學習呢?
(1)、是基于什么協議實現的?
(2)、怎么發起請求?
(3)、怎么將請求轉化為符合協議的格式的?
(4)、使用什么傳輸協議傳輸?
(5)、響應端基于什么機制來接收請求?
(6)、怎么將流還原為傳輸格式的?
(7)、處理完畢后怎么回應?
5.1、Spring-Remoting
? ? ? ?Spring-remoting是Spring提供java領域的遠程通訊框架,基于此框架,同樣也可以很簡單的將普通的spring bean以某種遠程協議的方式來發布,同樣也可以配置spring bean為遠程調用的bean。
(1)、是基于什么協議實現的?
作為一個遠程通訊的框架,Spring通過集成多種遠程通訊的library,從而實現了對多種協議的支持,例如rmi、http+io、xml-rpc、binary-rpc等。
(4)、怎么發起請求?
在Spring中,由于其對于遠程調用的bean采用的是proxy實現,發起請求完全是通過服務接口調用的方式。
(3)、怎么將請求轉化為符合協議的格式的?
Spring按照協議方式將請求的對象信息轉化為流,例如Spring Http Invoker是基于Spring自己定義的一個協議來實現的,傳輸協議上采用的為http,請求信息是基于java串行化機制轉化為流進行傳輸。
(4)、使用什么傳輸協議傳輸?
支持多種傳輸協議,例如rmi、http等等。
(5)、響應端基于什么機制來接收請求?
響應端遵循協議方式來接收請求,對于使用者而言,則只需通過spring的配置方式將普通的spring bean配置為響應端或者說提供服務端。
(6)、怎么將流還原為傳輸格式的?
按照協議方式來進行還原。
(7)、處理完畢后怎么回應?
處理完畢后直接返回即可,spring-remoting將根據協議方式來做相應的序列化。
5.2、Hessian
? ? ? ?Hessian是由caucho提供的一個基于binary-RPC實現的遠程通訊library。
(1)、是基于什么協議實現的?
基于Binary-RPC協議實現。
(2)、怎么發起請求?
需通過Hessian本身提供的API來發起請求。
(3)、怎么將請求轉化為符合協議的格式的?
Hessian通過其自定義的串行化機制將請求信息進行序列化,產生二進制流。
(4)、使用什么傳輸協議傳輸?
Hessian基于Http協議進行傳輸。
(5)、響應端基于什么機制來接收請求?
響應端根據Hessian提供的API來接收請求。
(6)、怎么將流還原為傳輸格式的?
Hessian根據其私有的串行化機制來將請求信息進行反序列化,傳遞給使用者時已是相應的請求信息對象了。
(7)、處理完畢后怎么回應?
處理完畢后直接返回,hessian將結果對象進行序列化,傳輸至調用端。
5.3、Burlap
? ? ? ?Burlap也是有caucho提供,它和hessian的不同在于,它是基于XML-RPC協議的。
(1)、是基于什么協議實現的?
基于XML-RPC協議實現。
(2)、怎么發起請求?
根據Burlap提供的API。
(3)、怎么將請求轉化為符合協議的格式的?
將請求信息轉化為符合協議的XML格式,轉化為流進行傳輸。
(4)、使用什么傳輸協議傳輸?
Http協議。
(5)、響應端基于什么機制來接收請求?
監聽Http請求。
(6)、怎么將流還原為傳輸格式的?
根據XML-RPC協議進行還原。
(7)、處理完畢后怎么回應?
返回結果寫入XML中,由Burlap返回至調用端。
5.4、XFire、Axis
? ? ? ?XFire、Axis是Webservice的實現框架,WebService可算是一個完整的SOA架構實現標準了,因此采用XFire、Axis這些也就意味著是采用webservice方式了。
(1)、是基于什么協議實現的?
基于SOAP協議。
(2)、怎么發起請求?
獲取到遠端service的proxy后直接調用。
(3)、怎么將請求轉化為符合協議的格式的?
將請求信息轉化為遵循SOAP協議的XML格式,由框架轉化為流進行傳輸。
(4)、使用什么傳輸協議傳輸?
Http協議。
(5)、響應端基于什么機制來接收請求?
監聽Http請求。
(6)、怎么將流還原為傳輸格式的?
根據SOAP協議進行還原。
(7)、處理完畢后怎么回應?
返回結果寫入XML中,由框架返回至調用端。
5.5、ActiveMQ
? ? ? ?ActiveMQ是JMS的實現,基于JMS這類消息機制實現遠程通訊是一種不錯的選擇,畢竟消息機制本身的功能使得基于它可以很容易的去實現同步/異步/單向調用等,而且消息機制從容錯角度上來說也是個不錯的選擇,這是Erlang能夠做到容錯的重要基礎。
(1)、是基于什么協議實現的?
基于JMS協議。
(2)、怎么發起請求?
遵循JMS API發起請求。
(3)、怎么將請求轉化為符合協議的格式的?
不太清楚,猜想應該是二進制流。
(4)、使用什么傳輸協議傳輸?
支持多種傳輸協議,例如socket、http等等。
(5)、響應端基于什么機制來接收請求?
監聽符合協議的端口。
(6)、怎么將流還原為傳輸格式的?
同問題3。
(7)、處理完畢后怎么回應?
遵循JMS API生成消息,并寫入JMS Queue中。
5.6、Mina
? ? ? ?Mina是Apache提供的通訊框架,在之前一直沒有提到網絡IO這塊,之前提及的框架或library基本都是基于BIO的,而Mina是采用NIO的,NIO在并發量增長時對比BIO而言會有明顯的性能提升,而java性能的提升,與其NIO這塊與OS的緊密結合是有不小的關系的。
(1)、是基于什么協議實現的?
基于純粹的Socket+NIO。
(2)、怎么發起請求?
通過Mina提供的Client API。
(3)、怎么將請求轉化為符合協議的格式的?
Mina遵循java串行化機制對請求對象進行序列化。
(4)、使用什么傳輸協議傳輸?
支持多種傳輸協議,例如socket、http等等。
(5)、響應端基于什么機制來接收請求?
以NIO的方式監聽協議端口。
(6)、怎么將流還原為傳輸格式的?
遵循java串行化機制對請求對象進行反序列化。
(7)、處理完畢后怎么回應?
遵循Mina API進行返回。
MINA是NIO方式的,因此支持異步調用是毫無懸念的。
六、RPC框架的發展與現狀
? ? ? ?RPC(Remote Procedure Call)是一種遠程調用協議,簡單地說就是能使應用像調用本地方法一樣的調用遠程的過程或服務,可以應用在分布式服務、分布式計算、遠程服務調用等許多場景。說起 RPC 大家并不陌生,業界有很多開源的優秀 RPC 框架,例如 Dubbo、Thrift、gRPC、Hprose 等等。下面先簡單介紹一下 RPC 與常用遠程調用方式的特點,以及一些優秀的開源 RPC 框架。
? ? ? ?RPC 與其它遠程調用方式比較,RPC 與 HTTP、RMI、Web Service 都能完成遠程調用,但是實現方式和側重點各有不同。
6.1、RPC與HTTP
? ? ? ?HTTP(HyperText Transfer Protocol)是應用層通信協議,使用標準語義訪問指定資源(圖片、接口等),網絡中的中轉服務器能識別協議內容。HTTP 協議是一種資源訪問協議,通過 HTTP 協議可以完成遠程請求并返回請求結果。
? ? ? ?HTTP 的優點是簡單、易用、可理解性強且語言無關,在遠程服務調用中包括微博有著廣泛應用。HTTP 的缺點是協議頭較重,一般請求到具體服務器的鏈路較長,可能會有 DNS 解析、Nginx 代理等。
? ? ? ?RPC 是一種協議規范,可以把 HTTP 看作是一種 RPC 的實現,也可以把 HTTP 作為 RPC 的傳輸協議來應用。RPC 服務的自動化程度比較高,能夠實現強大的服務治理功能,和語言結合更友好,性能也十分優秀。與 HTTP 相比,RPC 的缺點就是相對復雜,學習成本稍高。
6.2、RPC與RMI
? ? ? ?RMI(Remote Method Invocation)是指 Java 語言中的遠程方法調用,RMI 中的每個方法都具有方法簽名,RMI 客戶端和服務器端通過方法簽名進行遠程方法調用。RMI 只能在 Java 語言中使用,可以把 RMI 看作面向對象的 Java RPC。
6.3、RPC與Web Service
? ? ? ?Web Service 是一種基于 Web 進行服務發布、查詢、調用的架構方式,重點在于服務的管理與使用。Web Service 一般通過 WSDL 描述服務,使用 SOAP通過 HTTP 調用服務。
? ? ? ?RPC 是一種遠程訪問協議,而 Web Service 是一種體系結構,Web Service 也可以通過 RPC 來進行服務調用,因此 Web Service 更適合同一個 RPC 框架進行比較。當 RPC 框架提供了服務的發現與管理,并使用 HTTP 作為傳輸協議時,其實就是 Web Service。
? ? ? ?相對 Web Service,RPC 框架可以對服務進行更細粒度的治理,包括流量控制、SLA 管理等,在微服務化、分布式計算方面有更大的優勢。
? ? ? ?RPC 可基于 HTTP 或 TCP 協議,Web Service 就是基于 HTTP 協議的 RPC,它具有良好的跨平臺性,但其性能卻不如基于 TCP 協議的 RPC。會兩方面會直接影響 RPC 的性能,一是傳輸方式,二是序列化。
? ? ? ?眾所周知,TCP 是傳輸層協議,HTTP 是應用層協議,而傳輸層較應用層更加底層,在數據傳輸方面,越底層越快,因此,在一般情況下,TCP 一定比 HTTP 快。
七、總結
? ? ? ?在遠程通訊領域中,涉及的知識點還是相當的多的,例如有:通信協議(Socket/tcp/http/udp/rmi/xml-rpc etc.)、消息機制、網絡IO(BIO/NIO/AIO)、MultiThread、本地調用與遠程調用的透明化方案(涉及java classloader、Dynamic Proxy、Unit Test etc.)、異步與同步調用、網絡通信處理機制(自動重連、廣播、異常、池處理等等)、Java Serialization (各種協議的私有序列化機制等)、各種框架的實現原理(傳輸格式、如何將傳輸格式轉化為流的、如何將請求信息轉化為傳輸格式的、如何接收流的、如何將流還原為傳輸格式的等等),要精通其中的哪些東西,得根據實際需求來決定了,只有在了解了原理的情況下才能很容易的做出選擇,甚至可以根據需求做私有的遠程通訊協議,對于從事分布式服務平臺或開發較大型的分布式應用的人而言,我覺得至少上面提及的知識點是需要比較了解的。
?
總結
以上是生活随笔為你收集整理的Java远程通讯技术及原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 论文浅尝 | 知识图谱的不确定性衡量
- 下一篇: 论文浅尝 - ACL2020 | 利用知