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