RPC与其实现方式概念笔记
一,消息隊(duì)列服務(wù)一般用于設(shè)計(jì)多系統(tǒng)之間的信息傳輸,一般這種傳輸不需要對(duì)方對(duì)數(shù)據(jù)做出回應(yīng)。它最常見(jiàn)的方式是構(gòu)建異步的生產(chǎn)者-消費(fèi)者模式。我們?cè)谙到y(tǒng)開(kāi)發(fā)中,有些業(yè)務(wù)并不需要及時(shí)返回結(jié)果,我們可以把這些操作放到隊(duì)列中,然后另起一個(gè)消費(fèi)者去處理它。比如日志,數(shù)據(jù)庫(kù)異步更新。
二,rpc一般是用于服務(wù)器與服務(wù)器進(jìn)程之間通信,這種通信有請(qǐng)求和應(yīng)答。它是建立在底層的socket通信之上的。封裝為rpc之后,更加方便建立通信。就像在同一個(gè)進(jìn)程中調(diào)用對(duì)方的方法一樣。它本地的方法名一般和請(qǐng)求到達(dá)的服務(wù)器的方法名一一對(duì)應(yīng)。這樣可以更好的把模塊劃分。所以它是應(yīng)對(duì)分布式而生的。比如一個(gè)網(wǎng)站,一開(kāi)始可能所有的服務(wù)在一個(gè)進(jìn)程中,但是隨著業(yè)務(wù)的增長(zhǎng),一個(gè)進(jìn)程處理不過(guò)來(lái),這時(shí)就需要把業(yè)務(wù)拆分成多個(gè),分部到不同的機(jī)器上去。
https://zhidao.baidu.com/question/1642201290435943100.html
至于RPC框架,無(wú)非就是序列化與反序列化+網(wǎng)絡(luò)通信,你要愿意的話自己設(shè)計(jì)都行。懶得設(shè)計(jì)的話用框架無(wú)可厚非,但沒(méi)你想的差別那么大。
Spring RMI Dubbo Netty grpc protobufthriftRabbitMQ Kafka選型
https://www.zhihu.com/question/52445645
目前,Spring支持四種遠(yuǎn)程技術(shù):
- 遠(yuǎn)程方法調(diào)用(RMI)。通過(guò)使用?RmiProxyFactoryBean?和?RmiServiceExporter,Spring同時(shí)支持傳統(tǒng)的RMI(使用 java.rmi.Remote接口和java.rmi.RemoteException)和通過(guò)RMI調(diào)用器實(shí)現(xiàn)的透明遠(yuǎn)程調(diào)用(支持任何Java接口)。
- Spring的HTTP調(diào)用器。Spring提供了一種特殊的允許通過(guò)HTTP進(jìn)行Java串行化的遠(yuǎn)程調(diào)用策略,支持任意Java接口(就像RMI調(diào)用器)。相對(duì)應(yīng)的支持類是?HttpInvokerProxyFactoryBean和?HttpInvokerServiceExporter。
- Hessian。通過(guò)?HessianProxyFactoryBean?和?HessianServiceExporter,可以使用Caucho提供的基于HTTP的輕量級(jí)二進(jìn)制協(xié)議來(lái)透明地暴露服務(wù)。
- Burlap。?Burlap是Caucho的另外一個(gè)子項(xiàng)目,可以作為Hessian基于XML的替代方案。Spring提供了諸如?BurlapProxyFactoryBean?和?BurlapServiceExporter?的支持類。
- JAX RPC。Spring通過(guò)JAX-RPC為遠(yuǎn)程Web服務(wù)提供支持。
- JMS(待實(shí)現(xiàn))。
http://www.cnblogs.com/whatlonelytear/p/5841152.html
Spring除了使用基于HTTP協(xié)議的遠(yuǎn)程調(diào)用方案,還為開(kāi)發(fā)者提供了基于RMI機(jī)制的遠(yuǎn)程調(diào)用方法,RMI遠(yuǎn)程調(diào)用網(wǎng)絡(luò)通信實(shí)現(xiàn)是基于TCP/IP協(xié)議完成的,而不是通過(guò)HTTP協(xié)議。
在Spring RMI實(shí)現(xiàn)中,集成了標(biāo)準(zhǔn)的RMI-JRIM解決方案,該方案是java虛擬機(jī)實(shí)現(xiàn)的一部分,它使用java序列化來(lái)完成對(duì)象的傳輸,是一個(gè)java到j(luò)ava環(huán)境的分布式處理技術(shù),不涉及異構(gòu)平臺(tái)的處理。
http://blog.csdn.net/chjttony/article/details/6567802
前言:之前對(duì)于RPC方面的學(xué)習(xí)多限于對(duì)RMI原理的學(xué)習(xí),直到今天在看陳康賢前輩的《大型分布式網(wǎng)站架構(gòu)-設(shè)計(jì)與實(shí)踐》這本書(shū)的時(shí)候,才發(fā)現(xiàn)原來(lái)RPC可以基于TCP協(xié)議也可以基于HTTP協(xié)議
在Java中,可以利用Socket API實(shí)現(xiàn)基于TCP協(xié)議的RPC調(diào)用,由服務(wù)的調(diào)用方與服務(wù)的提供方建立Socket連接,并由服務(wù)的調(diào)用方通過(guò)Socket將需要調(diào)用的接口名稱、方法名稱和參數(shù)序列化后傳遞給服務(wù)的提供方,服務(wù)的提供方反序列化后再利用反射調(diào)用相關(guān)的方法,最后將結(jié)果返回給服務(wù)的調(diào)用方。整個(gè)基于TCP協(xié)議的PRC調(diào)用大致如此,但是在實(shí)例應(yīng)用中則會(huì)進(jìn)行一系列的封裝,譬如RMI便是在TCP協(xié)議上傳遞可序列化的java對(duì)象。
而基于HTTP協(xié)議的RPC調(diào)用則更像是我們?cè)L問(wèn)網(wǎng)頁(yè)一樣,只是它的返回結(jié)果更加單一簡(jiǎn)單。其大致流程為:由服務(wù)的調(diào)用者向服務(wù)的提供者發(fā)送請(qǐng)求,這種請(qǐng)求的方式可能是GET、POST、PUT、DELETE等中的一種(服務(wù)的提供者可能會(huì)根據(jù)不同的請(qǐng)求方式做出不同的處理,或者某個(gè)方法只允許某種請(qǐng)求方式),而調(diào)用的具體方法則根據(jù)URL進(jìn)行方法調(diào)用,而方法所需參數(shù)則可能是對(duì)服務(wù)調(diào)用方傳輸過(guò)去的XML數(shù)據(jù)或JSON數(shù)據(jù)解析后的結(jié)果,最后返回JOSN或XML的數(shù)據(jù)結(jié)果(這需要根據(jù)實(shí)際應(yīng)用定義相關(guān)的協(xié)議)。由于目前有很多開(kāi)源的WEB服務(wù)器,如Tomcat,JBoss等,所以其實(shí)現(xiàn)起來(lái)更加容易(就跟做Web項(xiàng)目一樣)。
而基于TCP協(xié)議實(shí)現(xiàn)的RPC調(diào)用,由于TCP協(xié)議處于協(xié)議棧的下層,能夠更加靈活地對(duì)協(xié)議字段進(jìn)行定制,減少網(wǎng)絡(luò)開(kāi)銷,提高性能,實(shí)現(xiàn)更大的吞吐量和并發(fā)數(shù)。但是需要更多地關(guān)注底層復(fù)雜的細(xì)節(jié),實(shí)現(xiàn)的代價(jià)更高。同時(shí)對(duì)于不同平臺(tái)(如安卓、IOS等),需要重新開(kāi)發(fā)出不同的工具包來(lái)進(jìn)行請(qǐng)求發(fā)送和響應(yīng)解析,工作量大,難以快速響應(yīng)和滿足 用戶需求。
基于HTTP協(xié)議實(shí)現(xiàn)的RPC則可以使用JSON和XML格式的請(qǐng)求或響應(yīng)數(shù)據(jù),而JSON和XML作為通用的格式標(biāo)準(zhǔn),開(kāi)源的解析工具已經(jīng)相當(dāng)成熟,在其上進(jìn)行二次開(kāi)發(fā)會(huì)非常便捷和簡(jiǎn)單。但是由于HTTP協(xié)議是上層協(xié)議,發(fā)送包含同等內(nèi)容的信息,使用HTTP協(xié)議傳輸所占用的字節(jié)數(shù)會(huì)比使用TCP協(xié)議傳輸所占用的字節(jié)數(shù)更高。因此,同等網(wǎng)絡(luò)環(huán)境下,通過(guò)HTTP協(xié)議傳輸相同內(nèi)容,效率會(huì)比基于TCP協(xié)議的數(shù)據(jù)效率要低,信息傳輸所占的時(shí)間也會(huì)更長(zhǎng)
http://blog.csdn.net/t894690230/article/details/50634855
隨著系統(tǒng)業(yè)務(wù)的不斷發(fā)展增長(zhǎng),對(duì)服務(wù)的壓力逐漸增大,一方面可以通過(guò)硬件的方式提高系統(tǒng)的性能;另一方面,可以通過(guò)軟件的方式來(lái)實(shí)現(xiàn)系統(tǒng)整體的性能。主流的解決方案,就是講一個(gè)比較大的系統(tǒng)不斷進(jìn)行拆分,拆分為獨(dú)立的服務(wù)系統(tǒng),不同服務(wù)系統(tǒng)之間通過(guò)HTTP請(qǐng)求進(jìn)行通信,或者其他協(xié)議進(jìn)行通信。RPC就是不同系統(tǒng)之間相互通信交換數(shù)據(jù)服務(wù)的有利工具;
(1)序列化 (Serialization)是將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问降倪^(guò)程。在序列化期間,對(duì)象將其當(dāng)前狀態(tài)寫(xiě)入到臨時(shí)或持久性存儲(chǔ)區(qū)。以后,可以通過(guò)從存儲(chǔ)區(qū)中讀取或反序列化對(duì)象的狀態(tài),重新創(chuàng)建該對(duì)象。
(2)之所以要進(jìn)行序列化,是因?yàn)樵诰W(wǎng)絡(luò)上進(jìn)行傳輸?shù)脑?#xff0c;無(wú)論任何類型的數(shù)據(jù),最終都需要轉(zhuǎn)化為二進(jìn)制流在網(wǎng)絡(luò)上傳輸。
(3)數(shù)據(jù)的發(fā)送方需要將傳輸?shù)膶?duì)象轉(zhuǎn)化為二進(jìn)制流才能在網(wǎng)絡(luò)上進(jìn)行傳輸,這也就是序列化的過(guò)程;數(shù)據(jù)的接收方則需要將接受到的二進(jìn)制流在恢復(fù)為對(duì)象,這個(gè)過(guò)程就是對(duì)象的反序列化的過(guò)程。
序列化和反序列化的方式有很多,常見(jiàn)的有使用Java本身內(nèi)置的序列化方式、Hession、JSON、XML等。Java內(nèi)置的可以直接使用Java提供的類不需要引用其他jar包,但是效率不是很高,下邊是一張各種序列化空間和性能對(duì)比:
解析性能:
序列化之空間開(kāi)銷:
基于Java內(nèi)置的序列化和反序列化關(guān)鍵代碼實(shí)現(xiàn):
首先,遠(yuǎn)程控制調(diào)用RPC的本質(zhì)還是底層的Scoket通信。對(duì)于簡(jiǎn)單的設(shè)計(jì)實(shí)現(xiàn)來(lái)說(shuō),其基本思路是:
1、服務(wù)的調(diào)用方Consumer通過(guò)Socket建立起與服務(wù)的提供方Provider的連接; 2、Consumer將需要調(diào)用的方法名稱和參數(shù)通過(guò)Socket發(fā)送給Provider;(序列化) 3、Provider獲取Consumer請(qǐng)求的數(shù)據(jù)并進(jìn)行解析(反序列化),執(zhí)行具體的某一個(gè)方法,構(gòu)造返回?cái)?shù)據(jù),返回給Consumer; 4、Consumer獲得Provider返回的數(shù)據(jù)進(jìn)行相應(yīng)的處理;(反序列化+展示)- 1
- 2
- 3
- 4
http://blog.csdn.net/xlgen157387/article/details/53543009? ?有demo
一般通信分為同步的和異步的。異步的基本都是用消息隊(duì)列完成,
對(duì)于了消息的序列化有很多種方式,最終傳的基本都是二進(jìn)制,不管是使用什么協(xié)議序列化的。具體的序列化案例就不說(shuō)了,因?yàn)樘嗔?#xff0c;如json,protobuf。
對(duì)于同步的通信,本質(zhì)上都是基于socket的RPC,例如Thrift,gRPC,JsonRPC,RESTful API(webservice)等
TCP RPC和HTTP RPC相比, TCP RPC的優(yōu)勢(shì)在哪里呢?一般說(shuō)是性能問(wèn)題,很多人說(shuō)到http的頭多了一些數(shù)據(jù)占用帶寬,還有長(zhǎng)連接的問(wèn)題。事實(shí)是SPDY,http2已經(jīng)是長(zhǎng)連接了,做設(shè)計(jì)RPC的時(shí)候,不妨考慮http吧,使用http RPC有很多次管理上的好處,例如可以使用nginx,tengine做負(fù)載均衡,運(yùn)營(yíng)web網(wǎng)站的工具基本都是可以用的。有個(gè)大牛說(shuō),用http rpc可以很輕松做到7層網(wǎng)絡(luò),但是使用TCP RPC就蛋疼了。Google開(kāi)源的gRPC就是基于http2設(shè)計(jì)的,我相信Google這樣做是有原因的。在支持http長(zhǎng)連接的環(huán)境下,使用TCP RPC不會(huì)有特別明顯的優(yōu)勢(shì)。
http://blog.csdn.net/xlgen157387/article/details/53543009
至于傳輸層上,運(yùn)用的是TCP協(xié)議、UDP協(xié)議、亦或是HTTP協(xié)議,一概不關(guān)心。
衡量一個(gè)RPC框架性能的好壞與否,RPC的網(wǎng)絡(luò)I/O模型的選擇,至關(guān)重要。在此基礎(chǔ)上,設(shè)計(jì)出來(lái)的RPC服務(wù)器,可以考慮支持阻塞式同步IO、非阻塞式同步IO、當(dāng)然還有所謂的多路復(fù)用IO模型、異步IO模型。支持不同的網(wǎng)絡(luò)IO模型,在高并發(fā)的狀態(tài)下,處理性能上會(huì)有很大的差別。還有一個(gè)衡量的標(biāo)準(zhǔn),就是選擇的傳輸協(xié)議。是基于TCP協(xié)議、還是HTTP協(xié)議、還是UDP協(xié)議?對(duì)性能也有一定的影響。但是從我目前了解的情況來(lái)看,大多數(shù)RPC開(kāi)源實(shí)現(xiàn)框架都是基于TCP、或者HTTP的,目測(cè)沒(méi)有采用UDP協(xié)議做為主要的傳輸協(xié)議的。(tomcat底層阻塞io)
明白了RPC的使用原理和性能要求。現(xiàn)在,我們能不能撇開(kāi)那些RPC開(kāi)源框架,自己動(dòng)手開(kāi)發(fā)一個(gè)高性能的RPC服務(wù)器呢?我想,還是可以的。現(xiàn)在本人就使用Java,基于Netty,開(kāi)發(fā)實(shí)現(xiàn)一個(gè)高性能的RPC服務(wù)器。
為了提高單個(gè)節(jié)點(diǎn)的通信吞吐量,提高通信性能。如果是基于Java后端的,一般首選的是NIO框架(No-block IO)。但是問(wèn)題也來(lái)了,Java的NIO掌握起來(lái)要相當(dāng)?shù)募夹g(shù)功底,和足夠的技術(shù)積累,使用起來(lái)才能得心應(yīng)手。一般的開(kāi)發(fā)人員,如果要使用NIO開(kāi)發(fā)一個(gè)后端的TCP/HTTP服務(wù)器,附帶考慮TCP粘包、網(wǎng)絡(luò)通信異常、消息鏈接處理等等網(wǎng)絡(luò)通信細(xì)節(jié),開(kāi)發(fā)門(mén)檻太高,所以比較明智的選擇是,采用業(yè)界主流的NIO框架進(jìn)行服務(wù)器后端開(kāi)發(fā)。主流的NIO框架主要有Netty、Mina。它們主要都是基于TCP通信,非阻塞的IO、靈活的IO線程池而設(shè)計(jì)的,應(yīng)對(duì)高并發(fā)請(qǐng)求也是綽綽有余。隨著Netty、Mina這樣優(yōu)秀的NIO框架,設(shè)計(jì)上日趨完善,Java后端高性能服務(wù)器開(kāi)發(fā),在技術(shù)上提供了有力的支持保障,從而打破了C++在服務(wù)器后端,一統(tǒng)天下的局面。因?yàn)樵诖酥?#xff0c;Java的NIO一直受人詬病,讓人敬而遠(yuǎn)之!
技術(shù)原理:
1、定義RPC請(qǐng)求消息、應(yīng)答消息結(jié)構(gòu),里面要包括RPC的接口定義模塊、包括遠(yuǎn)程調(diào)用的類名、方法名稱、參數(shù)結(jié)構(gòu)、參數(shù)值等信息。
2、服務(wù)端初始化的時(shí)候通過(guò)容器加載RPC接口定義和RPC接口實(shí)現(xiàn)類對(duì)象的映射關(guān)系,然后等待客戶端發(fā)起調(diào)用請(qǐng)求。
3、客戶端發(fā)起的RPC消息里面包含,遠(yuǎn)程調(diào)用的類名、方法名稱、參數(shù)結(jié)構(gòu)、參數(shù)值等信息,通過(guò)網(wǎng)絡(luò),以字節(jié)流的方式送給RPC服務(wù)端,RPC服務(wù)端接收到字節(jié)流的請(qǐng)求之后,去對(duì)應(yīng)的容器里面,查找客戶端接口映射的具體實(shí)現(xiàn)對(duì)象。
4、RPC服務(wù)端找到實(shí)現(xiàn)對(duì)象的參數(shù)信息,通過(guò)反射機(jī)制創(chuàng)建該對(duì)象的實(shí)例,并返回調(diào)用處理結(jié)果,最后封裝成RPC應(yīng)答消息通知到客戶端。
5、客戶端通過(guò)網(wǎng)絡(luò),收到字節(jié)流形式的RPC應(yīng)答消息,進(jìn)行拆包、解析之后,顯示遠(yuǎn)程調(diào)用結(jié)果。
上面說(shuō)的是很簡(jiǎn)單,但是實(shí)現(xiàn)的時(shí)候,我們還要考慮如下的問(wèn)題:
1、RPC服務(wù)器的傳輸層是基于TCP協(xié)議的,出現(xiàn)粘包咋辦?這樣客戶端的請(qǐng)求,服務(wù)端不是會(huì)解析失敗?好在Netty里面已經(jīng)提供了解決TCP粘包問(wèn)題的解碼器:LengthFieldBasedFrameDecoder,可以靠它輕松搞定TCP粘包問(wèn)題。
2、Netty服務(wù)端的線程模型是單線程、多線程(一個(gè)線程負(fù)責(zé)客戶端連接,連接成功之后,丟給后端IO的線程池處理)、還是主從模式(客戶端連接、后端IO處理都是基于線程池的實(shí)現(xiàn))。當(dāng)然在這里,我出于性能考慮,使用了Netty主從線程池模型。
3、Netty的IO處理線程池,如果遇到非常耗時(shí)的業(yè)務(wù),出現(xiàn)阻塞了咋辦?這樣不是很容易把后端的NIO線程給掛死、阻塞?本文的處理方式是,對(duì)于復(fù)雜的后端業(yè)務(wù),分派到專門(mén)的業(yè)務(wù)線程池里面,進(jìn)行異步回調(diào)處理。
4、RPC消息的傳輸是通過(guò)字節(jié)流在NIO的通道(Channel)之間傳輸,那具體如何實(shí)現(xiàn)呢?本文,是通過(guò)基于Java原生對(duì)象序列化機(jī)制的編碼、解碼器(ObjectEncoder、ObjectDecoder)進(jìn)行實(shí)現(xiàn)的。當(dāng)然出于性能考慮,這個(gè)可能不是最優(yōu)的方案。更優(yōu)的方案是把消息的編碼、解碼器,搞成可以配置實(shí)現(xiàn)的。具體比如可以通過(guò):protobuf、JBoss?Marshalling方式進(jìn)行解碼和編碼,以提高網(wǎng)絡(luò)消息的傳輸效率。
5、RPC服務(wù)器要考慮多線程、高并發(fā)的使用場(chǎng)景,所以線程安全是必須的。此外盡量不要使用synchronized進(jìn)行加鎖,改用輕量級(jí)的ReentrantLock方式進(jìn)行代碼塊的條件加鎖。比如本文中的RPC消息處理回調(diào),就有這方面的使用。
6、RPC服務(wù)端的服務(wù)接口對(duì)象和服務(wù)接口實(shí)現(xiàn)對(duì)象要能輕易的配置,輕松進(jìn)行加載、卸載。在這里,本文是通過(guò)Spring容器進(jìn)行統(tǒng)一的對(duì)象管理。
談?wù)勅绾问褂肗etty開(kāi)發(fā)實(shí)現(xiàn)高性能的RPC服務(wù)器、Netty實(shí)現(xiàn)高性能RPC服務(wù)器優(yōu)化篇之消息序列化。這兩篇文章主要設(shè)計(jì)的思路是,基于Netty構(gòu)建了一個(gè)高性能的RPC服務(wù)器,
http://www.cnblogs.com/jietang/p/5615681.html? ?有demo? *******
為什么說(shuō)要搞定微服務(wù)架構(gòu),先搞定RPC框架?
http://www.jianshu.com/p/70391a203667? 通篇圖文并茂,非常好的解釋了rpc
###RPC: HTTP vs. TCP
| TCP | 處于協(xié)議棧的下層,可以對(duì)協(xié)議字段進(jìn)行定制,減少網(wǎng)絡(luò)開(kāi)銷字節(jié)數(shù),降低網(wǎng)絡(luò)開(kāi)銷,提高性能,實(shí)現(xiàn)更大的吞吐量和并發(fā)數(shù) | 實(shí)現(xiàn)成本高(需要考慮多線程并發(fā)、鎖、I/O etc 復(fù)雜的底層細(xì)節(jié)),難以跨平臺(tái) |
| HTTP | 很多成熟的容器已經(jīng)很好處理, like. Tomcat, Apache, Jboss; 成熟的響應(yīng)格式,like. JSON, XML | 處于協(xié)議棧的上層,同等內(nèi)容信息比 TCP的字節(jié)數(shù)多,效率相對(duì)要低 => gzip 改善 |
https://my.oschina.net/u/2890903/blog/736059
主要參考書(shū):大型分布式網(wǎng)站架構(gòu)-設(shè)計(jì)與實(shí)踐? ?深入分布式緩存
轉(zhuǎn)載于:https://www.cnblogs.com/silyvin/p/9106759.html
總結(jié)
以上是生活随笔為你收集整理的RPC与其实现方式概念笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python 压缩 解压
- 下一篇: 多线程中join()的用法