#0 系列目錄#java
在分佈式服務框架中,一個最基礎的問題就是遠程服務是怎麼通信的,在Java領域中有不少可實現遠程通信的技術
,例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,這些名詞之間究竟是些什麼關係呢,它們背後究竟是基於什麼原理實現的呢,瞭解這些是實現分佈式服務框架的基礎知識,而若是在性能上有高的要求的話,那深刻了解這些技術背後的機制就是必須的了。web
#1 基本原理# 要實現網絡機器間的通信,首先得來看看計算機系統網絡通訊的基本原理,在底層層面去看,網絡通訊須要作的就是將流從一臺計算機傳輸到另一臺計算機,基於傳輸協議和網絡IO來實現,其中傳輸協議比較出名的有tcp、udp等等,tcp、udp都是在基於Socket概念上爲某類應用場景而擴展出的傳輸協議,網絡IO,主要有bio、nio、aio三種方式,全部的分佈式應用通信都基於這個原理而實現
,只是爲了應用的易用,各類語言一般都會提供一些更爲貼近應用易用的應用層協議。spring
#2 消息模式# 歸根結底,企業應用系統就是對數據的處理,而對於一個擁有多個子系統的企業應用系統而言,它的基礎支撐無疑就是對消息的處理。與對象不一樣,消息本質上是一種數據結構(固然,對象也能夠看作是一種特殊的消息),它包含消費者與服務雙方都能識別的數據,這些數據須要在不一樣的進程(機器)之間進行傳遞,並可能會被多個徹底不一樣的客戶端消費
。消息傳遞相較文件傳遞與遠程過程調用(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),負責協調消息、隊列與路徑尋址之間關係。
#3 應用級協議# 遠程服務通信,須要達到的目標是在一臺計算機發起請求,另一臺機器在接收到請求後進行相應的處理並將結果返回給請求端,這其中又會有諸如one way request、同步請求、異步請求等等請求方式,按照網絡通訊原理,須要實現這個須要作的就是將請求轉換成流,經過傳輸協議傳輸至遠端,遠端計算機在接收到請求的流後進行處理,處理完畢後將結果轉化爲流,並經過傳輸協議返回給調用端
。
原理是這樣的,但爲了應用的方便,業界推出了不少基於此原理之上的應用級的協議,使得你們能夠不用去直接操做這麼底層的東西,一般應用級的遠程通訊協議會提供:
提供一種更加易用或貼合語言的標準傳輸格式
;替你完成了將傳輸格式轉化爲流
,經過某種傳輸協議傳輸至遠端計算機,遠端計算機在接收到流後轉化爲傳輸格式,並進行存儲或以某種方式通知遠端計算機。因此在學習應用級的遠程通訊協議時,咱們能夠帶着這幾個問題進行學習:
不過應用級的遠程通訊協議並不會在傳輸協議上作什麼多大的改進,主要是在流操做方面,讓應用層生成流和處理流的這個過程更加的貼合所使用的語言或標準,至於傳輸協議則一般都是可選的
,在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的一次完整的遠程通訊過程的原理:
客戶端發起請求,請求轉交至RMI客戶端的stub類;
stub類將請求的接口、方法、參數等信息進行序列化;
基於socket將序列化後的流傳輸至服務器端;
服務器端接收到流後轉發至相應的skelton類;
skelton類將請求的信息反序列化後調用實際的處理類;
處理類處理完畢後將結果返回給skelton類;
Skelton類將結果序列化,經過socket將流傳送給客戶端的stub;
stub在接收到流後反序列化,將反序列化後的Java Object返回給調用者。
根據原理來回答下以前學習應用級協議帶着的幾個問題:
是Java ObjectStream。
基於Java串行化機制將請求的java object信息轉化爲流。
根據採用的協議啓動相應的監聽端口,當有流進入後基於Java串行化機制將流進行反序列化,並根據RMI協議獲取到相應的處理對象信息,進行調用並處理,處理完畢後的結果一樣基於java串行化機制進行返回。
Socket。
##3.2 XML-RPC## RPC使用C/S方式,採用http協議
,發送請求到服務器,等待服務器返回結果。這個請求包括一個參數集和一個文本集,一般造成「classname.methodname」形式
。優勢是跨語言跨平臺,C端、S端有更大的獨立性,缺點是不支持對象,沒法在編譯器檢查錯誤,只能在運行期檢查。
XML-RPC也是一種和RMI相似的遠程調用的協議,它和RMI的不一樣之處在於它以標準的xml格式來定義請求的信息(請求的對象、方法、參數等),這樣的好處是什麼呢,就是在跨語言通信的時候也可使用
。
來看下XML-RPC協議的一次遠程通訊過程:
客戶端發起請求,按照XML-RPC協議將請求信息進行填充;
填充完畢後將xml轉化爲流,經過傳輸協議進行傳輸;
接收到在接收到流後轉換爲xml,按照XML-RPC協議獲取請求的信息並進行處理;
處理完畢後將結果按照XML-RPC協議寫入xml中並返回。
一樣來回答問題:
標準格式的XML。
將XML轉化爲流。
經過監聽的端口獲取到請求的流,轉化爲XML,並根據協議獲取請求的信息,進行處理並將結果寫入XML中返回。
Http。
##3.3 Binary-RPC## Binary-RPC看名字就知道和XML-RPC是差很少的了,不一樣之處僅在於傳輸的標準格式由XML轉爲了二進制的格式
。
一樣來回答問題:
標準格式的二進制文件。
將二進制格式文件轉化爲流。
經過監聽的端口獲取到請求的流,轉化爲二進制文件,根據協議獲取請求的信息,進行處理並將結果寫入XML中返回。
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個層次:
Http傳輸信道;
XML的數據格式;
SOAP封裝格式;
WSDL的描述方式;
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中的一次遠程通訊的過程:
客戶端將請求轉化爲符合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也是經常使用的實現遠程異步調用的方法之一。
#4 之間的區別# ##4.1 RPC與RMI##
RPC跨語言,而RMI只支持Java
。
RMI調用遠程對象方法,容許方法返回Java對象以及基本數據類型
,而RPC不支持對象的概念,傳送到RPC服務的消息由外部數據表示 (External Data Representation, XDR) 語言表示,這種語言抽象了字節序類和數據類型結構之間的差別
。只有由 XDR 定義的數據類型才能被傳遞,能夠說 RMI 是面向對象方式的Java RPC。
在方法調用上,RMI中,遠程接口使每一個遠程方法都具備方法簽名。若是一個方法在服務器上執行,可是沒有相匹配的簽名被添加到這個遠程接口上,那麼這個新方法就不能被RMI客戶方所調用
。
在RPC中,當一個請求到達RPC服務器時,這個請求就包含了一個參數集和一個文本值,一般造成「classname.methodname」的形式
。這就向RPC服務器代表,被請求的方法在爲 「classname」的類中,名叫「methodname」。而後RPC服務器就去搜索與之相匹配的類和方法,並把它做爲那種方法參數類型的輸入
。這裏的參數類型是與RPC請求中的類型是匹配的。一旦匹配成功,這個方法就被調用了,其結果被編碼後返回客戶方。
RPC自己沒有規範,但基本的工做機制是同樣的,即:serialization/deserialization+stub+skeleton,寬泛的講,只要能實現遠程調用,都是RPC
,如:rmi .net-remoting ws/soap/rest hessian xmlrpc thrift potocolbuffer。
在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的跨平臺各有千秋吧。
#5 可選實現技術# 目前java領域可用於實現遠程通信的框架或library,知名的有:JBoss-Remoting、Spring-Remoting、Hessian、Burlap、XFire(Axis)、ActiveMQ、Mina、Mule、EJB3等等,來對每種作個簡單的介紹和評價,其實呢,要作分佈式服務框架,這些東西都是要有很是深入的瞭解的,由於分佈式服務框架實際上是包含了解決分佈式領域以及應用層面領域兩方面問題的
。
固然,你也能夠本身根據遠程網絡通訊原理(transport protocol+Net IO)去實現本身的通信框架或library。
那麼在瞭解這些遠程通信的框架或library時,會帶着什麼問題去學習呢?
##5.1 Spring-Remoting## Spring-remoting是Spring提供java領域的遠程通信框架,基於此框架,一樣也能夠很簡單的將普通的spring bean以某種遠程協議的方式來發布,一樣也能夠配置spring bean爲遠程調用的bean。
做爲一個遠程通信的框架,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將根據協議方式來作相應的序列化。
##5.2 Hessian## Hessian是由caucho提供的一個基於binary-RPC實現的遠程通信library。
基於Binary-RPC協議實現。
需經過Hessian自己提供的API來發起請求。
Hessian經過其自定義的串行化機制將請求信息進行序列化,產生二進制流。
Hessian基於Http協議進行傳輸。
響應端根據Hessian提供的API來接收請求。
Hessian根據其私有的串行化機制來將請求信息進行反序列化,傳遞給使用者時已經是相應的請求信息對象了。
處理完畢後直接返回,hessian將結果對象進行序列化,傳輸至調用端。
##5.3 Burlap## Burlap也是有caucho提供,它和hessian的不一樣在於,它是基於XML-RPC協議的。
基於XML-RPC協議實現。
根據Burlap提供的API。
將請求信息轉化爲符合協議的XML格式,轉化爲流進行傳輸。
Http協議。
監聽Http請求。
根據XML-RPC協議進行還原。
返回結果寫入XML中,由Burlap返回至調用端。
##5.4 XFire、Axis## XFire、Axis是Webservice的實現框架,WebService可算是一個完整的SOA架構實現標準了,所以採用XFire、Axis這些也就意味着是採用webservice方式了。
基於SOAP協議。
獲取到遠端service的proxy後直接調用。
將請求信息轉化爲遵循SOAP協議的XML格式,由框架轉化爲流進行傳輸。
Http協議。
監聽Http請求。
根據SOAP協議進行還原。
返回結果寫入XML中,由框架返回至調用端。
##5.5 ActiveMQ## ActiveMQ是JMS的實現,基於JMS這類消息機制實現遠程通信是一種不錯的選擇,畢竟消息機制自己的功能使得基於它能夠很容易的去實現同步/異步/單向調用等,並且消息機制從容錯角度上來講也是個不錯的選擇
,這是Erlang可以作到容錯的重要基礎。
基於JMS協議。
遵循JMS API發起請求。
不太清楚,猜測應該是二進制流。
支持多種傳輸協議,例如socket、http等等。
監聽符合協議的端口。
同問題3。
遵循JMS API生成消息,並寫入JMS Queue中。
##5.6 Mina## Mina是Apache提供的通信框架,在以前一直沒有提到網絡IO這塊,以前說起的框架或library基本都是基於BIO的,而Mina是採用NIO的,NIO在併發量增加時對比BIO而言會有明顯的性能提高,而java性能的提高,與其NIO這塊與OS的緊密結合是有不小的關係的
。
基於純粹的Socket+NIO。
經過Mina提供的Client API。
Mina遵循java串行化機制對請求對象進行序列化。
支持多種傳輸協議,例如socket、http等等。
以NIO的方式監聽協議端口。
遵循java串行化機制對請求對象進行反序列化。
遵循Mina API進行返回。
MINA是NIO方式的,所以支持異步調用是毫無懸念的。
#6 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 快。
#7 總結# 在遠程通信領域中,涉及的知識點仍是至關的多的,例若有:通訊協議(Socket/tcp/http/udp/rmi/xml-rpc etc.)、消息機制、網絡IO(BIO/NIO/AIO)、MultiThread、本地調用與遠程調用的透明化方案(涉及java classloader、Dynamic Proxy、Unit Test etc.)、異步與同步調用、網絡通訊處理機制(自動重連、廣播、異常、池處理等等)、Java Serialization (各類協議的私有序列化機制等)、各類框架的實現原理(傳輸格式、如何將傳輸格式轉化爲流的、如何將請求信息轉化爲傳輸格式的、如何接收流的、如何將流還原爲傳輸格式的等等)
,要精通其中的哪些東西,得根據實際需求來決定了,只有在瞭解了原理的狀況下才能很容易的作出選擇,甚至能夠根據需求作私有的遠程通信協議,對於從事分佈式服務平臺或開發較大型的分佈式應用的人而言,我以爲至少上面說起的知識點是須要比較瞭解的。
#讚揚個人文章給您帶來收穫#