摘要:微軟的雖然引入了事件機(jī)制,可以在隊(duì)列收到消息時(shí)觸發(fā)事件,通知訂閱者。由微軟作為主要貢獻(xiàn)者的,則對(duì)以及做了進(jìn)一層包裝,并能夠很好地實(shí)現(xiàn)這一模式。
在分布式服務(wù)框架中,一個(gè)最基礎(chǔ)的問(wèn)題就是遠(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ī)制就是必須的了。
1 基本原理要實(shí)現(xiàn)網(wǎng)絡(luò)機(jī)器間的通訊,首先得來(lái)看看計(jì)算機(jī)系統(tǒng)網(wǎng)絡(luò)通信的基本原理,在底層層面去看,網(wǎng)絡(luò)通信需要做的就是將流從一臺(tái)計(jì)算機(jī)傳輸?shù)搅硗庖慌_(tái)計(jì)算機(jī),基于傳輸協(xié)議和網(wǎng)絡(luò)IO來(lái)實(shí)現(xiàn),其中傳輸協(xié)議比較出名的有tcp、udp等等,tcp、udp都是在基于Socket概念上為某類應(yīng)用場(chǎng)景而擴(kuò)展出的傳輸協(xié)議,網(wǎng)絡(luò)IO,主要有bio、nio、aio三種方式,所有的分布式應(yīng)用通訊都基于這個(gè)原理而實(shí)現(xiàn),只是為了應(yīng)用的易用,各種語(yǔ)言通常都會(huì)提供一些更為貼近應(yīng)用易用的應(yīng)用層協(xié)議。
2 消息模式歸根結(jié)底,企業(yè)應(yīng)用系統(tǒng)就是對(duì)數(shù)據(jù)的處理,而對(duì)于一個(gè)擁有多個(gè)子系統(tǒng)的企業(yè)應(yīng)用系統(tǒng)而言,它的基礎(chǔ)支撐無(wú)疑就是對(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)程過(guò)程調(diào)用(RPC)而言,似乎更勝一籌,因?yàn)樗哂懈玫钠脚_(tái)無(wú)關(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)者的“無(wú)知”。事實(shí)上,該模式可以支持多個(gè)生產(chǎn)者與消費(fèi)者。例如,我們可以讓多個(gè)生產(chǎn)者向消息通道發(fā)送消息,因?yàn)橄M(fèi)者對(duì)生產(chǎn)者的無(wú)知性,它不必考慮究竟是哪個(gè)生產(chǎn)者發(fā)來(lái)的消息。
雖然消息通道解除了生產(chǎn)者與消費(fèi)者之間的耦合,使得我們可以任意地對(duì)生產(chǎn)者與消費(fèi)者進(jìn)行擴(kuò)展,但它又同時(shí)引入了各自對(duì)消息通道的依賴,因?yàn)樗鼈儽仨氈劳ǖ蕾Y源的位置。要解除這種對(duì)通道的依賴,可以考慮引入Lookup服務(wù)來(lái)查找該通道資源。例如,在JMS中就可以通過(guò)JNDI來(lái)獲取消息通道Queue。若要做到充分的靈活性,可以將與通道相關(guān)的信息存儲(chǔ)到配置文件中,Lookup服務(wù)首先通過(guò)讀取配置文件來(lái)獲得通道。
消息通道通常以隊(duì)列的形式存在,這種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)無(wú)疑最為適合這種處理消息的場(chǎng)景。微軟的MSMQ、IBM MQ、JBoss MQ以及開(kāi)源的RabbitMQ、Apache ActiveMQ都通過(guò)隊(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í)例并開(kāi)始調(diào)用時(shí),jboss jndi的實(shí)現(xiàn)方法是從jnp server上獲取對(duì)象實(shí)例,將其序列化回本地,然后在本地進(jìn)行反序列化,之后在本地進(jìn)行類調(diào)用。
通過(guò)這個(gè)機(jī)制,就可以知道了,本地其實(shí)是必須有綁定到j(luò)boss上的對(duì)象實(shí)例的class的,否則反序列化的時(shí)候肯定就失敗了,而遠(yuǎn)程通訊需要做到的是在遠(yuǎn)程執(zhí)行某動(dòng)作,并獲取到相應(yīng)的結(jié)果,可見(jiàn)純粹基于JNDI是無(wú)法實(shí)現(xiàn)遠(yuǎn)程通訊的。
但JNDI也是實(shí)現(xiàn)分布式服務(wù)框架一個(gè)很關(guān)鍵的技術(shù)點(diǎn),因?yàn)榭梢酝ㄟ^(guò)它來(lái)實(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)方式,通過(guò)調(diào)用傳遞過(guò)來(lái)的消費(fèi)者對(duì)象獲取更多細(xì)節(jié)消息。
在基于消息的分布式系統(tǒng)中,拉模型的消費(fèi)者通常以Batch Job的形式,根據(jù)事先設(shè)定的時(shí)間間隔,定期偵聽(tīng)通道的情況。一旦發(fā)現(xiàn)有消息傳遞進(jìn)來(lái),就會(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)者無(wú)需了解生產(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ì)通道的依賴,通過(guò)后臺(tái)任務(wù)去定期訪問(wèn)消息通道。壞處是需要引入一個(gè)多帶帶的服務(wù)進(jìn)程,以Schedule形式執(zhí)行。而對(duì)于推模型而言,消息通道事實(shí)上會(huì)作為消費(fèi)者觀察的主體,一旦發(fā)現(xiàn)消息進(jìn)入,就會(huì)通知消費(fèi)者執(zhí)行對(duì)消息的處理。無(wú)論推模型,拉模型,對(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)傳來(lái)的客戶信息,并根據(jù)傳遞過(guò)來(lái)的客戶信息,進(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)模式無(wú)論是Message Channel模式,還是Publisher-Subscriber模式,隊(duì)列在其中都扮演了舉足輕重的角色。然而,在企業(yè)應(yīng)用系統(tǒng)中,當(dāng)系統(tǒng)變得越來(lái)越復(fù)雜時(shí),對(duì)性能的要求也會(huì)越來(lái)越高,此時(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ò)消息路由,我們可以配置路由規(guī)則指定消息傳遞的路徑,以及指定具體的消費(fèi)者消費(fèi)對(duì)應(yīng)的生產(chǎn)者。例如指定路由的關(guān)鍵字,并由它來(lái)綁定具體的隊(duì)列與指定的生產(chǎn)者(或消費(fèi)者)。路由的支持提供了消息傳遞與處理的靈活性,也有利于提高整個(gè)系統(tǒng)的消息處理能力。同時(shí),路由對(duì)象有效地封裝了尋找與匹配消息路徑的邏輯,就好似一個(gè)調(diào)停者(Meditator),負(fù)責(zé)協(xié)調(diào)消息、隊(duì)列與路徑尋址之間關(guān)系。
3 應(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)換成流,通過(guò)傳輸協(xié)議傳輸至遠(yuǎn)端,遠(yuǎn)端計(jì)算機(jī)在接收到請(qǐng)求的流后進(jìn)行處理,處理完畢后將結(jié)果轉(zhuǎn)化為流,并通過(guò)傳輸協(xié)議返回給調(diào)用端。
原理是這樣的,但為了應(yīng)用的方便,業(yè)界推出了很多基于此原理之上的應(yīng)用級(jí)的協(xié)議,使得大家可以不用去直接操作這么底層的東西,通常應(yīng)用級(jí)的遠(yuǎn)程通信協(xié)議會(huì)提供:
為了避免直接做流操作這么麻煩,提供一種更加易用或貼合語(yǔ)言的標(biāo)準(zhǔn)傳輸格式;
網(wǎng)絡(luò)通信機(jī)制的實(shí)現(xiàn),就是替你完成了將傳輸格式轉(zhuǎn)化為流,通過(guò)某種傳輸協(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è)問(wèn)題進(jìn)行學(xué)習(xí):
傳輸?shù)臉?biāo)準(zhǔn)格式是什么?
怎么樣將請(qǐng)求轉(zhuǎn)化為傳輸?shù)牧鳎?/p>
怎么接收和處理流?
傳輸協(xié)議是?
不過(guò)應(yīng)用級(jí)的遠(yuǎn)程通信協(xié)議并不會(huì)在傳輸協(xié)議上做什么多大的改進(jìn),主要是在流操作方面,讓應(yīng)用層生成流和處理流的這個(gè)過(guò)程更加的貼合所使用的語(yǔ)言或標(biāo)準(zhǔn),至于傳輸協(xié)議則通常都是可選的,在java領(lǐng)域中知名的有:RMI、XML-RPC、Binary-RPC、SOAP、CORBA、JMS、HTTP,來(lái)具體的看看這些遠(yuǎn)程通信的應(yīng)用級(jí)協(xié)議。
3.1 RMI(遠(yuǎn)程方法調(diào)用)RMI是個(gè)典型的為java定制的遠(yuǎn)程通信協(xié)議,我們都知道,在single vm中,我們可以通過(guò)直接調(diào)用java object instance來(lái)實(shí)現(xiàn)通信,那么在遠(yuǎn)程通信時(shí),如果也能按照這種方式當(dāng)然是最好了,這種遠(yuǎn)程通信的機(jī)制成為RPC(Remote Procedure Call),RMI正是朝著這個(gè)目標(biāo)而誕生的。
RMI 采用stubs 和 skeletons 來(lái)進(jìn)行遠(yuǎn)程對(duì)象(remote object)的通訊。stub 充當(dāng)遠(yuǎn)程對(duì)象的客戶端代理,有著和遠(yuǎn)程對(duì)象相同的遠(yuǎn)程接口,遠(yuǎn)程對(duì)象的調(diào)用實(shí)際是通過(guò)調(diào)用該對(duì)象的客戶端代理對(duì)象stub來(lái)完成的,通過(guò)該機(jī)制RMI就好比它是本地工作,采用tcp/ip協(xié)議,客戶端直接調(diào)用服務(wù)端上的一些方法。優(yōu)點(diǎn)是強(qiáng)類型,編譯期可檢查錯(cuò)誤,缺點(diǎn)是只能基于JAVA語(yǔ)言,客戶機(jī)與服務(wù)器緊耦合。
來(lái)看下基于RMI的一次完整的遠(yuǎn)程通信過(guò)程的原理:
客戶端發(fā)起請(qǐng)求,請(qǐng)求轉(zhuǎn)交至RMI客戶端的stub類;
stub類將請(qǐng)求的接口、方法、參數(shù)等信息進(jìn)行序列化;
基于socket將序列化后的流傳輸至服務(wù)器端;
服務(wù)器端接收到流后轉(zhuǎn)發(fā)至相應(yīng)的skelton類;
skelton類將請(qǐng)求的信息反序列化后調(diào)用實(shí)際的處理類;
處理類處理完畢后將結(jié)果返回給skelton類;
Skelton類將結(jié)果序列化,通過(guò)socket將流傳送給客戶端的stub;
stub在接收到流后反序列化,將反序列化后的Java Object返回給調(diào)用者。
根據(jù)原理來(lái)回答下之前學(xué)習(xí)應(yīng)用級(jí)協(xié)議帶著的幾個(gè)問(wèn)題:
傳輸?shù)臉?biāo)準(zhǔn)格式是什么?是Java ObjectStream。
怎么樣將請(qǐng)求轉(zhuǎn)化為傳輸?shù)牧鳎?/strong>基于Java串行化機(jī)制將請(qǐng)求的java object信息轉(zhuǎn)化為流。
怎么接收和處理流?根據(jù)采用的協(xié)議啟動(dòng)相應(yīng)的監(jiān)聽(tīng)端口,當(dāng)有流進(jìn)入后基于Java串行化機(jī)制將流進(jìn)行反序列化,并根據(jù)RMI協(xié)議獲取到相應(yīng)的處理對(duì)象信息,進(jìn)行調(diào)用并處理,處理完畢后的結(jié)果同樣基于java串行化機(jī)制進(jìn)行返回。
傳輸協(xié)議是?Socket。
3.2 XML-RPCRPC使用C/S方式,采用http協(xié)議,發(fā)送請(qǐng)求到服務(wù)器,等待服務(wù)器返回結(jié)果。這個(gè)請(qǐng)求包括一個(gè)參數(shù)集和一個(gè)文本集,通常形成“classname.methodname”形式。優(yōu)點(diǎn)是跨語(yǔ)言跨平臺(tái),C端、S端有更大的獨(dú)立性,缺點(diǎn)是不支持對(duì)象,無(wú)法在編譯器檢查錯(cuò)誤,只能在運(yùn)行期檢查。
XML-RPC也是一種和RMI類似的遠(yuǎn)程調(diào)用的協(xié)議,它和RMI的不同之處在于它以標(biāo)準(zhǔn)的xml格式來(lái)定義請(qǐng)求的信息(請(qǐng)求的對(duì)象、方法、參數(shù)等),這樣的好處是什么呢,就是在跨語(yǔ)言通訊的時(shí)候也可以使用。
來(lái)看下XML-RPC協(xié)議的一次遠(yuǎn)程通信過(guò)程:
客戶端發(fā)起請(qǐng)求,按照XML-RPC協(xié)議將請(qǐng)求信息進(jìn)行填充;
填充完畢后將xml轉(zhuǎn)化為流,通過(guò)傳輸協(xié)議進(jìn)行傳輸;
接收到在接收到流后轉(zhuǎn)換為xml,按照XML-RPC協(xié)議獲取請(qǐng)求的信息并進(jìn)行處理;
處理完畢后將結(jié)果按照XML-RPC協(xié)議寫入xml中并返回。
同樣來(lái)回答問(wèn)題:
傳輸?shù)臉?biāo)準(zhǔn)格式是?標(biāo)準(zhǔn)格式的XML。
怎么樣將請(qǐng)求轉(zhuǎn)化為傳輸?shù)牧鳎?/strong>將XML轉(zhuǎn)化為流。
怎么接收和處理流?通過(guò)監(jiān)聽(tīng)的端口獲取到請(qǐng)求的流,轉(zhuǎn)化為XML,并根據(jù)協(xié)議獲取請(qǐng)求的信息,進(jìn)行處理并將結(jié)果寫入XML中返回。
傳輸協(xié)議是?Http。
3.3 Binary-RPCBinary-RPC看名字就知道和XML-RPC是差不多的了,不同之處僅在于傳輸?shù)臉?biāo)準(zhǔn)格式由XML轉(zhuǎn)為了二進(jìn)制的格式。
同樣來(lái)回答問(wèn)題:
傳輸?shù)臉?biāo)準(zhǔn)格式是?標(biāo)準(zhǔn)格式的二進(jìn)制文件。
怎么樣將請(qǐng)求轉(zhuǎn)化為傳輸?shù)牧鳎?/strong>將二進(jìn)制格式文件轉(zhuǎn)化為流。
怎么接收和處理流?通過(guò)監(jiān)聽(tīng)的端口獲取到請(qǐng)求的流,轉(zhuǎn)化為二進(jìn)制文件,根據(jù)協(xié)議獲取請(qǐng)求的信息,進(jìn)行處理并將結(jié)果寫入XML中返回。
傳輸協(xié)議是?Http。
3.4 SOAPSOAP原意為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)的。就是通過(guò)一個(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)行過(guò)程。
Web Service大體上分為5個(gè)層次:
Http傳輸信道;
XML的數(shù)據(jù)格式;
SOAP封裝格式;
WSDL的描述方式;
UDDI UDDI是一種目錄服務(wù),企業(yè)可以使用它對(duì)Webservices進(jìn)行注冊(cè)和搜索;
3.5 JMSJMS是實(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é)議,在其他的語(yǔ)言體系中也存在著類似JMS的東西,可以統(tǒng)一的將這類機(jī)制稱為消息機(jī)制,而消息機(jī)制呢,通常是高并發(fā)、分布式領(lǐng)域推薦的一種通信機(jī)制,這里的主要一個(gè)問(wèn)題是容錯(cuò)。
JMS是Java的消息服務(wù),JMS的客戶端之間可以通過(guò)JMS服務(wù)進(jìn)行異步的消息傳輸。JMS支持兩種消息模型:Point-to-Point(P2P)和Publish/Subscribe(Pub/Sub),即點(diǎn)對(duì)點(diǎn)和發(fā)布訂閱模型。
來(lái)看JMS中的一次遠(yuǎn)程通信的過(guò)程:
客戶端將請(qǐng)求轉(zhuǎn)化為符合JMS規(guī)定的Message;
通過(guò)JMS API將Message放入JMS Queue或Topic中;
如為JMS Queue,則發(fā)送中相應(yīng)的目標(biāo)Queue中,如為Topic,則發(fā)送給訂閱了此Topic的JMS Queue。
處理端則通過(guò)輪訓(xùn)JMS Queue,來(lái)獲取消息,接收到消息后根據(jù)JMS協(xié)議來(lái)解析Message并處理。
同樣來(lái)回答問(wèn)題:
傳輸?shù)臉?biāo)準(zhǔn)格式是?JMS規(guī)定的Message。
怎么樣將請(qǐng)求轉(zhuǎn)化為傳輸?shù)牧鳎?/strong>將參數(shù)信息放入Message中即可。
怎么接收和處理流?輪訓(xùn)JMSQueue來(lái)接收Message,接收到后進(jìn)行處理,處理完畢后仍然是以Message的方式放入Queue中發(fā)送或Multicast。
傳輸協(xié)議是?不限。
基于JMS也是常用的實(shí)現(xiàn)遠(yuǎn)程異步調(diào)用的方法之一。
4 之間的區(qū)別 4.1 RPC與RMIRPC跨語(yǔ)言,而RMI只支持Java。
RMI調(diào)用遠(yuǎn)程對(duì)象方法,允許方法返回Java對(duì)象以及基本數(shù)據(jù)類型,而RPC不支持對(duì)象的概念,傳送到RPC服務(wù)的消息由外部數(shù)據(jù)表示
(External Data Representation, XDR) 語(yǔ)言表示,這種語(yǔ)言抽象了字節(jié)序類和數(shù)據(jù)類型結(jié)構(gòu)之間的差異。只有由
XDR 定義的數(shù)據(jù)類型才能被傳遞,可以說(shuō) RMI 是面向?qū)ο蠓绞降腏ava RPC。
在方法調(diào)用上,RMI中,遠(yuǎn)程接口使每個(gè)遠(yuǎn)程方法都具有方法簽名。如果一個(gè)方法在服務(wù)器上執(zhí)行,但是沒(méi)有相匹配的簽名被添加到這個(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é)果被編碼后返回客戶方。
RPC本身沒(méi)有規(guī)范,但基本的工作機(jī)制是一樣的,即:serialization/deserialization+stub+skeleton,寬泛的講,只要能實(shí)現(xiàn)遠(yuǎn)程調(diào)用,都是RPC,如:rmi.net-remoting ws/soap/rest hessian xmlrpc thrift potocolbuffer。
在Java里提供了完整的sockets通訊接口,但sockets要求客戶端和服務(wù)端必須進(jìn)行應(yīng)用級(jí)協(xié)議的編碼交換數(shù)據(jù),采用sockets是非常麻煩的。一個(gè)代替Sockets的協(xié)議是RPC(RemoteProcedure Call), 它抽象出了通訊接口用于過(guò)程調(diào)用,使得編程者調(diào)用一個(gè)遠(yuǎn)程過(guò)程和調(diào)用本地過(guò)程同樣方便。RPC系統(tǒng)采用XDR來(lái)編碼遠(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 RemoteMethod 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ù)和返回值是通過(guò)網(wǎng)絡(luò)傳送的(是請(qǐng)求應(yīng)答機(jī)制)。
RMI一般都是同步的,也就是說(shuō),當(dāng)client調(diào)用Server的一個(gè)方法的時(shí)候,需要等到對(duì)方的返回,才能繼續(xù)執(zhí)行client端,這個(gè)過(guò)程調(diào)用本地方法感覺(jué)上是一樣的,這也是RMI的一個(gè)特點(diǎn)。JMS一般只是一個(gè)點(diǎn)發(fā)出一個(gè)Message到Message Server,發(fā)出之后一般不會(huì)關(guān)心誰(shuí)用了這個(gè)message。所以,一般RMI的應(yīng)用是緊耦合,JMS的應(yīng)用相對(duì)來(lái)說(shuō)是松散耦合應(yīng)用。
4.3 Webservice與RMIRMI是在tcp協(xié)議上傳遞可序列化的java對(duì)象,只能用在java虛擬機(jī)上,綁定語(yǔ)言,客戶端和服務(wù)端都必須是java。webservice沒(méi)有這個(gè)限制,webservice是在http協(xié)議上傳遞xml文本文件,與語(yǔ)言和平臺(tái)無(wú)關(guān)。
4.4 Webservice與JMSWebservice專注于遠(yuǎn)程服務(wù)調(diào)用,jms專注于信息交換。
大多數(shù)情況下Webservice是兩系統(tǒng)間的直接交互(Consumer Producer),而大多數(shù)情況下jms是三方系統(tǒng)交互(Consumer 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沒(méi)考慮異構(gòu)系統(tǒng),說(shuō)白了,JMS就沒(méi)考慮非java的東西。但是好在現(xiàn)在大多數(shù)的jms provider(就是JMS的各種實(shí)現(xiàn)產(chǎn)品)都解決了異構(gòu)問(wèn)題。相比WebService的跨平臺(tái)各有千秋吧。
5 可選實(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等等,來(lái)對(duì)每種做個(gè)簡(jiǎn)單的介紹和評(píng)價(jià),其實(shí)呢,要做分布式服務(wù)框架,這些東西都是要有非常深刻的了解的,因?yàn)榉植际椒?wù)框架其實(shí)是包含了解決分布式領(lǐng)域以及應(yīng)用層面領(lǐng)域兩方面問(wèn)題的。
當(dāng)然,你也可以自己根據(jù)遠(yuǎn)程網(wǎng)絡(luò)通信原理(transport protocol+Net IO)去實(shí)現(xiàn)自己的通訊框架或library。
那么在了解這些遠(yuǎn)程通訊的框架或library時(shí),會(huì)帶著什么問(wèn)題去學(xué)習(xí)呢?
是基于什么協(xié)議實(shí)現(xiàn)的?
怎么發(fā)起請(qǐng)求?
怎么將請(qǐng)求轉(zhuǎn)化為符合協(xié)議的格式的?
使用什么傳輸協(xié)議傳輸?
響應(yīng)端基于什么機(jī)制來(lái)接收請(qǐng)求?
怎么將流還原為傳輸格式的?
處理完畢后怎么回應(yīng)?
5.1 Spring-RemotingSpring-remoting是Spring提供java領(lǐng)域的遠(yuǎn)程通訊框架,基于此框架,同樣也可以很簡(jiǎn)單的將普通的spring bean以某種遠(yuǎn)程協(xié)議的方式來(lái)發(fā)布,同樣也可以配置spring bean為遠(yuǎn)程調(diào)用的bean。
是基于什么協(xié)議實(shí)現(xiàn)的?作為一個(gè)遠(yuǎn)程通訊的框架,Spring通過(guò)集成多種遠(yuǎn)程通訊的library,從而實(shí)現(xiàn)了對(duì)多種協(xié)議的支持,例如rmi、http+io、xml-rpc、binary-rpc等。
怎么發(fā)起請(qǐng)求?在Spring中,由于其對(duì)于遠(yuǎn)程調(diào)用的bean采用的是proxy實(shí)現(xiàn),發(fā)起請(qǐng)求完全是通過(guò)服務(wù)接口調(diào)用的方式。
怎么將請(qǐng)求轉(zhuǎn)化為符合協(xié)議的格式的?Spring按照協(xié)議方式將請(qǐng)求的對(duì)象信息轉(zhuǎn)化為流,例如Spring Http
Invoker是基于Spring自己定義的一個(gè)協(xié)議來(lái)實(shí)現(xiàn)的,傳輸協(xié)議上采用的為http,請(qǐng)求信息是基于java串行化機(jī)制轉(zhuǎn)化為流進(jìn)行傳輸。
使用什么傳輸協(xié)議傳輸?支持多種傳輸協(xié)議,例如rmi、http等等。
響應(yīng)端基于什么機(jī)制來(lái)接收請(qǐng)求?響應(yīng)端遵循協(xié)議方式來(lái)接收請(qǐng)求,對(duì)于使用者而言,則只需通過(guò)spring的配置方式將普通的spring
bean配置為響應(yīng)端或者說(shuō)提供服務(wù)端。
怎么將流還原為傳輸格式的?按照協(xié)議方式來(lái)進(jìn)行還原。
處理完畢后怎么回應(yīng)?處理完畢后直接返回即可,spring-remoting將根據(jù)協(xié)議方式來(lái)做相應(yīng)的序列化。
5.2 HessianHessian是由caucho提供的一個(gè)基于binary-RPC實(shí)現(xiàn)的遠(yuǎn)程通訊library。
是基于什么協(xié)議實(shí)現(xiàn)的?基于Binary-RPC協(xié)議實(shí)現(xiàn)。
怎么發(fā)起請(qǐng)求?需通過(guò)Hessian本身提供的API來(lái)發(fā)起請(qǐng)求。
怎么將請(qǐng)求轉(zhuǎn)化為符合協(xié)議的格式的?Hessian通過(guò)其自定義的串行化機(jī)制將請(qǐng)求信息進(jìn)行序列化,產(chǎn)生二進(jìn)制流。
使用什么傳輸協(xié)議傳輸?Hessian基于Http協(xié)議進(jìn)行傳輸。
響應(yīng)端基于什么機(jī)制來(lái)接收請(qǐng)求?響應(yīng)端根據(jù)Hessian提供的API來(lái)接收請(qǐng)求。
怎么將流還原為傳輸格式的?Hessian根據(jù)其私有的串行化機(jī)制來(lái)將請(qǐng)求信息進(jìn)行反序列化,傳遞給使用者時(shí)已是相應(yīng)的請(qǐng)求信息對(duì)象了。
處理完畢后怎么回應(yīng)?處理完畢后直接返回,hessian將結(jié)果對(duì)象進(jìn)行序列化,傳輸至調(diào)用端。
5.3 BurlapBurlap也是有caucho提供,它和hessian的不同在于,它是基于XML-RPC協(xié)議的。
是基于什么協(xié)議實(shí)現(xiàn)的?基于XML-RPC協(xié)議實(shí)現(xiàn)。
怎么發(fā)起請(qǐng)求?根據(jù)Burlap提供的API。
怎么將請(qǐng)求轉(zhuǎn)化為符合協(xié)議的格式的?將請(qǐng)求信息轉(zhuǎn)化為符合協(xié)議的XML格式,轉(zhuǎn)化為流進(jìn)行傳輸。
使用什么傳輸協(xié)議傳輸?Http協(xié)議。
響應(yīng)端基于什么機(jī)制來(lái)接收請(qǐng)求?監(jiān)聽(tīng)Http請(qǐng)求。
怎么將流還原為傳輸格式的?根據(jù)XML-RPC協(xié)議進(jìn)行還原。
處理完畢后怎么回應(yīng)?返回結(jié)果寫入XML中,由Burlap返回至調(diào)用端。
5.4 XFire、AxisXFire、Axis是Webservice的實(shí)現(xiàn)框架,WebService可算是一個(gè)完整的SOA架構(gòu)實(shí)現(xiàn)標(biāo)準(zhǔn)了,因此采用XFire、Axis這些也就意味著是采用webservice方式了。
是基于什么協(xié)議實(shí)現(xiàn)的?基于SOAP協(xié)議。
怎么發(fā)起請(qǐng)求?獲取到遠(yuǎn)端service的proxy后直接調(diào)用。
怎么將請(qǐng)求轉(zhuǎn)化為符合協(xié)議的格式的?將請(qǐng)求信息轉(zhuǎn)化為遵循SOAP協(xié)議的XML格式,由框架轉(zhuǎn)化為流進(jìn)行傳輸。
使用什么傳輸協(xié)議傳輸?Http協(xié)議。
響應(yīng)端基于什么機(jī)制來(lái)接收請(qǐng)求?監(jiān)聽(tīng)Http請(qǐng)求。
怎么將流還原為傳輸格式的?根據(jù)SOAP協(xié)議進(jìn)行還原。
處理完畢后怎么回應(yīng)?返回結(jié)果寫入XML中,由框架返回至調(diào)用端。
ActiveMQ是JMS的實(shí)現(xiàn),基于JMS這類消息機(jī)制實(shí)現(xiàn)遠(yuǎn)程通訊是一種不錯(cuò)的選擇,畢竟消息機(jī)制本身的功能使得基于它可以很容易的去實(shí)現(xiàn)同步/異步/單向調(diào)用等,而且消息機(jī)制從容錯(cuò)角度上來(lái)說(shuō)也是個(gè)不錯(cuò)的選擇,這是Erlang能夠做到容錯(cuò)的重要基礎(chǔ)。
是基于什么協(xié)議實(shí)現(xiàn)的?基于JMS協(xié)議。
怎么發(fā)起請(qǐng)求?遵循JMS API發(fā)起請(qǐng)求。
怎么將請(qǐng)求轉(zhuǎn)化為符合協(xié)議的格式的?不太清楚,猜想應(yīng)該是二進(jìn)制流。
使用什么傳輸協(xié)議傳輸?支持多種傳輸協(xié)議,例如socket、http等等。
響應(yīng)端基于什么機(jī)制來(lái)接收請(qǐng)求?監(jiān)聽(tīng)符合協(xié)議的端口。
怎么將流還原為傳輸格式的?同問(wèn)題3。
處理完畢后怎么回應(yīng)?遵循JMS API生成消息,并寫入JMS Queue中。
5.6 MinaMina是Apache提供的通訊框架,在之前一直沒(méi)有提到網(wǎng)絡(luò)IO這塊,之前提及的框架或library基本都是基于BIO的,而Mina是采用NIO的,NIO在并發(fā)量增長(zhǎng)時(shí)對(duì)比BIO而言會(huì)有明顯的性能提升,而java性能的提升,與其NIO這塊與OS的緊密結(jié)合是有不小的關(guān)系的。
是基于什么協(xié)議實(shí)現(xiàn)的?基于純粹的Socket+NIO。
怎么發(fā)起請(qǐng)求?通過(guò)Mina提供的Client API。
怎么將請(qǐng)求轉(zhuǎn)化為符合協(xié)議的格式的?Mina遵循java串行化機(jī)制對(duì)請(qǐng)求對(duì)象進(jìn)行序列化。
使用什么傳輸協(xié)議傳輸?支持多種傳輸協(xié)議,例如socket、http等等。
響應(yīng)端基于什么機(jī)制來(lái)接收請(qǐng)求?以NIO的方式監(jiān)聽(tīng)協(xié)議端口。
怎么將流還原為傳輸格式的?遵循java串行化機(jī)制對(duì)請(qǐng)求對(duì)象進(jìn)行反序列化。
處理完畢后怎么回應(yīng)?遵循Mina API進(jìn)行返回。
MINA是NIO方式的,因此支持異步調(diào)用是毫無(wú)懸念的。
6 RPC框架的發(fā)展與現(xiàn)狀RPC(Remote Procedure Call)是一種遠(yuǎn)程調(diào)用協(xié)議,簡(jiǎn)單地說(shuō)就是能使應(yīng)用像調(diào)用本地方法一樣的調(diào)用遠(yuǎn)程的過(guò)程或服務(wù),可以應(yīng)用在分布式服務(wù)、分布式計(jì)算、遠(yuǎn)程服務(wù)調(diào)用等許多場(chǎng)景。說(shuō)起 RPC 大家并不陌生,業(yè)界有很多開(kāi)源的優(yōu)秀 RPC 框架,例如 Dubbo、Thrift、gRPC、Hprose 等等。下面先簡(jiǎn)單介紹一下 RPC 與常用遠(yuǎn)程調(diào)用方式的特點(diǎn),以及一些優(yōu)秀的開(kāi)源 RPC 框架。
RPC 與其它遠(yuǎn)程調(diào)用方式比較,RPC 與 HTTP、RMI、Web Service 都能完成遠(yuǎn)程調(diào)用,但是實(shí)現(xiàn)方式和側(cè)重點(diǎn)各有不同。
6.1 RPC與HTTPHTTP(HyperText Transfer Protocol)是應(yīng)用層通信協(xié)議,使用標(biāo)準(zhǔn)語(yǔ)義訪問(wèn)指定資源(圖片、接口等),網(wǎng)絡(luò)中的中轉(zhuǎn)服務(wù)器能識(shí)別協(xié)議內(nèi)容。HTTP 協(xié)議是一種資源訪問(wèn)協(xié)議,通過(guò) HTTP 協(xié)議可以完成遠(yuǎn)程請(qǐng)求并返回請(qǐng)求結(jié)果。
HTTP 的優(yōu)點(diǎn)是簡(jiǎn)單、易用、可理解性強(qiáng)且語(yǔ)言無(wú)關(guān),在遠(yuǎn)程服務(wù)調(diào)用中包括微博有著廣泛應(yīng)用。HTTP 的缺點(diǎn)是協(xié)議頭較重,一般請(qǐng)求到具體服務(wù)器的鏈路較長(zhǎng),可能會(huì)有 DNS 解析、Nginx 代理等。
RPC 是一種協(xié)議規(guī)范,可以把 HTTP 看作是一種 RPC 的實(shí)現(xiàn),也可以把 HTTP 作為 RPC 的傳輸協(xié)議來(lái)應(yīng)用。RPC 服務(wù)的自動(dòng)化程度比較高,能夠?qū)崿F(xiàn)強(qiáng)大的服務(wù)治理功能,和語(yǔ)言結(jié)合更友好,性能也十分優(yōu)秀。與 HTTP 相比,RPC 的缺點(diǎn)就是相對(duì)復(fù)雜,學(xué)習(xí)成本稍高。
6.2 RPC與RMIRMI(Remote Method Invocation)是指 Java 語(yǔ)言中的遠(yuǎn)程方法調(diào)用,RMI 中的每個(gè)方法都具有方法簽名,RMI 客戶端和服務(wù)器端通過(guò)方法簽名進(jìn)行遠(yuǎn)程方法調(diào)用。RMI 只能在 Java 語(yǔ)言中使用,可以把 RMI 看作面向?qū)ο蟮?Java RPC。
說(shuō)到這里,順便給大家推薦一個(gè)Java方面中高級(jí)程度的架構(gòu)交流學(xué)習(xí)群:650385180,里面會(huì)分享一些資深架構(gòu)師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發(fā)、高性能、分布式、微服務(wù)架構(gòu)的原理,JVM性能優(yōu)化這些成為架構(gòu)師必備的知識(shí)體系。還能領(lǐng)取免費(fèi)的學(xué)習(xí)資源,相信對(duì)于已經(jīng)工作和遇到技術(shù)瓶頸的碼友,在這個(gè)群里會(huì)有你需要的內(nèi)容。
6.3 RPC與Web ServiceWeb Service 是一種基于 Web 進(jìn)行服務(wù)發(fā)布、查詢、調(diào)用的架構(gòu)方式,重點(diǎn)在于服務(wù)的管理與使用。Web Service 一般通過(guò) WSDL 描述服務(wù),使用 SOAP通過(guò) HTTP 調(diào)用服務(wù)。
RPC 是一種遠(yuǎn)程訪問(wèn)協(xié)議,而 Web Service 是一種體系結(jié)構(gòu),Web Service 也可以通過(guò) RPC 來(lái)進(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 快。
7 總結(jié)在遠(yuǎn)程通訊領(lǐng)域中,涉及的知識(shí)點(diǎn)還是相當(dāng)?shù)亩嗟模缬校和ㄐ艆f(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í)際需求來(lái)決定了,只有在了解了原理的情況下才能很容易的做出選擇,甚至可以根據(jù)需求做私有的遠(yuǎn)程通訊協(xié)議,對(duì)于從事分布式服務(wù)平臺(tái)或開(kāi)發(fā)較大型的分布式應(yīng)用的人而言,我覺(jué)得至少上面提及的知識(shí)點(diǎn)是需要比較了解的。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/11914.html
摘要:微軟的雖然引入了事件機(jī)制,可以在隊(duì)列收到消息時(shí)觸發(fā)事件,通知訂閱者。由微軟作為主要貢獻(xiàn)者的,則對(duì)以及做了進(jìn)一層包裝,并能夠很好地實(shí)現(xiàn)這一模式。 在分布式服務(wù)框架中,一個(gè)最基礎(chǔ)的問(wèn)題就是遠(yuǎn)程服務(wù)是怎么通訊的,在Java領(lǐng)域中有很多可實(shí)現(xiàn)遠(yuǎn)程通訊的技術(shù),例如:RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等,這些名詞之間到底是些什么關(guān)系呢,它們背后到底是基...
摘要:對(duì)于與而言,則可以看做是消息傳遞技術(shù)的一種衍生或封裝。在生產(chǎn)者通知消費(fèi)者時(shí),傳遞的往往是消息或事件,而非生產(chǎn)者自身。通過(guò)消息路由,我們可以配置路由規(guī)則指定消息傳遞的路徑,以及指定具體的消費(fèi)者消費(fèi)對(duì)應(yīng)的生產(chǎn)者。采用和來(lái)進(jìn)行遠(yuǎn)程對(duì)象的通訊。 消息模式 歸根結(jié)底,企業(yè)應(yīng)用系統(tǒng)就是對(duì)數(shù)據(jù)的處理,而對(duì)于一個(gè)擁有多個(gè)子系統(tǒng)的企業(yè)應(yīng)用系統(tǒng)而言,它的基礎(chǔ)支撐無(wú)疑就是對(duì)消息的處理。與對(duì)象不同,消息本質(zhì)上...
摘要:知乎的點(diǎn)贊,應(yīng)該還是可以參考的。除了網(wǎng)絡(luò)通信,還需要有高效的序列化框架,以及一種尋址方式,如果是帶會(huì)話狀態(tài)的調(diào)用,還需要有會(huì)話的狀態(tài)保持的功能。一般來(lái)說(shuō),框架實(shí)現(xiàn)的架構(gòu)原理都是類似的。服務(wù)端響應(yīng)主要是服務(wù)端業(yè)務(wù)邏輯實(shí)現(xiàn)。 本博客 貓叔的博客,轉(zhuǎn)載請(qǐng)申明出處 在我剛剛了解分布式的時(shí)候,經(jīng)常對(duì)RPC和分布式有些混淆,甚至一直以為兩者對(duì)等,所以我們先看看他們有什么區(qū)別? RPC實(shí)現(xiàn)了服務(wù)消費(fèi)...
摘要:知乎的點(diǎn)贊,應(yīng)該還是可以參考的。除了網(wǎng)絡(luò)通信,還需要有高效的序列化框架,以及一種尋址方式,如果是帶會(huì)話狀態(tài)的調(diào)用,還需要有會(huì)話的狀態(tài)保持的功能。一般來(lái)說(shuō),框架實(shí)現(xiàn)的架構(gòu)原理都是類似的。服務(wù)端響應(yīng)主要是服務(wù)端業(yè)務(wù)邏輯實(shí)現(xiàn)。 本博客 貓叔的博客,轉(zhuǎn)載請(qǐng)申明出處 在我剛剛了解分布式的時(shí)候,經(jīng)常對(duì)RPC和分布式有些混淆,甚至一直以為兩者對(duì)等,所以我們先看看他們有什么區(qū)別? RPC實(shí)現(xiàn)了服務(wù)消費(fèi)...
閱讀 2136·2021-11-22 15:22
閱讀 1285·2021-11-11 16:54
閱讀 1807·2021-09-23 11:32
閱讀 3007·2021-09-22 10:02
閱讀 1770·2019-08-30 12:59
閱讀 1085·2019-08-29 16:27
閱讀 621·2019-08-29 13:21
閱讀 2463·2019-08-28 17:57