RPC框架(一)RPC简介
- 一、概述
- 二、RPC
- 2.1、RPC定義
- 2.2、RPC主要組成部分
- 三、影響RPC框架性能的因素
- 四、工業(yè)界的 RPC 框架一覽
- 4.1、國(guó)內(nèi)
- 4.2、國(guó)外
- 五、如何選擇RPC框架
?
一、概述
隨著公司規(guī)模的擴(kuò)大,以及業(yè)務(wù)量的激增,單體應(yīng)用逐步演化為服務(wù)/微服務(wù)的架構(gòu)模式, 服務(wù)之間的調(diào)用大多采用rpc的方式調(diào)用,或者消息隊(duì)列的方式進(jìn)行解耦。幾乎每個(gè)大廠都會(huì)創(chuàng)建自己的rpc框架,或者基于知名的rpc框架進(jìn)行改造。
目前, rpc框架主要沿著兩條路線發(fā)展,一個(gè)是目標(biāo)為了跨語(yǔ)言,服務(wù)端可以用不同的語(yǔ)言實(shí)現(xiàn),客戶(hù)端也可以用不同的語(yǔ)言實(shí)現(xiàn),不同的語(yǔ)言實(shí)現(xiàn)的客戶(hù)端和服務(wù)器端可以互相調(diào)用。很顯然,要支持不同的語(yǔ)言,需要基于那種語(yǔ)言實(shí)現(xiàn)相同協(xié)議的框架,并且協(xié)議設(shè)計(jì)應(yīng)該也是跨語(yǔ)言的,其中比較典型的是 grpc,基于同一個(gè)IDL,可以生成不同語(yǔ)言的代碼,并且語(yǔ)言的支持也非常的多。
另一個(gè)rpc框架發(fā)展的目標(biāo)是支持服務(wù)治理,主要的精力放在服務(wù)發(fā)現(xiàn)、路由、容錯(cuò)處理等方面,主要圍繞一個(gè)語(yǔ)言開(kāi)發(fā),可能也有一些第三方曲折的實(shí)現(xiàn)服務(wù)的調(diào)用和服務(wù)的實(shí)現(xiàn),這其中的代表,也是比較早的開(kāi)源的框架就是阿里巴巴的dubbo。
有些rpc框架協(xié)議的涉及一開(kāi)始就沒(méi)有考慮的跨語(yǔ)言,其中使用了語(yǔ)言的一些特有的屬性,比如Java的ObjectInputStream/ObjectOutputStream, Golang的Gob等,有些在協(xié)議的設(shè)計(jì)上就考慮了通用性, 使用JSON或者Protobuffer作為數(shù)據(jù)序列化。
有些框架是基于TCP的二進(jìn)制流的數(shù)據(jù)傳輸,有些基于http的request/response模型進(jìn)行請(qǐng)求,也有基于http2的流式傳輸,更有一些支持可信賴(lài)的UDP進(jìn)行數(shù)據(jù)傳入,比如quic、kcp等。
有些提供了生態(tài)圈的一些框架,比如gateway、agent等,有些restful風(fēng)格的rpc框架天然支持API gateway進(jìn)行負(fù)載均衡。
二、RPC
2.1、RPC定義
RPC(Remote Procedure Call Protocol)遠(yuǎn)程過(guò)程調(diào)用協(xié)議。一個(gè)通俗的描述是:客戶(hù)端在不知道調(diào)用細(xì)節(jié)的情況下,調(diào)用存在于遠(yuǎn)程計(jì)算機(jī)上的某個(gè)對(duì)象,就像調(diào)用本地應(yīng)用程序中的對(duì)象一樣。比較正式的描述是:一種通過(guò)網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請(qǐng)求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。那么我們至少?gòu)倪@樣的描述中挖掘出幾個(gè)要點(diǎn):
-
RPC是協(xié)議:既然是協(xié)議就只是一套規(guī)范,那么就需要有人遵循這套規(guī)范來(lái)進(jìn)行實(shí)現(xiàn)。目前典型的RPC實(shí)現(xiàn)包括:Dubbo、Thrift、GRPC、Hetty等。這里要說(shuō)明一下,目前技術(shù)的發(fā)展趨勢(shì)來(lái)看,實(shí)現(xiàn)了RPC協(xié)議的應(yīng)用工具往往都會(huì)附加其他重要功能,例如Dubbo還包括了服務(wù)治等功能。
-
網(wǎng)絡(luò)協(xié)議和網(wǎng)絡(luò)IO模型對(duì)其透明:既然RPC的客戶(hù)端認(rèn)為自己是在調(diào)用本地對(duì)象。那么傳輸層使用的是TCP/UDP還是HTTP協(xié)議,又或者是一些其他的網(wǎng)絡(luò)協(xié)議它就不需要關(guān)心了。既然網(wǎng)絡(luò)協(xié)議對(duì)其透明,那么調(diào)用過(guò)程中,使用的是哪一種網(wǎng)絡(luò)IO模型調(diào)用者也不需要關(guān)心。
-
信息格式對(duì)其透明:我們知道在本地應(yīng)用程序中,對(duì)于某個(gè)對(duì)象的調(diào)用需要傳遞一些參數(shù),并且會(huì)返回一個(gè)調(diào)用結(jié)果。至于被調(diào)用的對(duì)象內(nèi)部是如何使用這些參數(shù),并計(jì)算出處理結(jié)果的,調(diào)用方是不需要關(guān)心的。那么對(duì)于遠(yuǎn)程調(diào)用來(lái)說(shuō),這些參數(shù)會(huì)以某種信息格式傳遞給網(wǎng)絡(luò)上的另外一臺(tái)計(jì)算機(jī),這個(gè)信息格式是怎樣構(gòu)成的,調(diào)用方是不需要關(guān)心的。
-
應(yīng)該有跨語(yǔ)言能力:為什么這樣說(shuō)呢?因?yàn)檎{(diào)用方實(shí)際上也不清楚遠(yuǎn)程服務(wù)器的應(yīng)用程序是使用什么語(yǔ)言運(yùn)行的。那么對(duì)于調(diào)用方來(lái)說(shuō),無(wú)論服務(wù)器方使用的是什么語(yǔ)言,本次調(diào)用都應(yīng)該成功,并且返回值也應(yīng)該按照調(diào)用方程序語(yǔ)言所能理解的形式進(jìn)行描述。
那么上面的描述情況可以用下圖表示:
2.2、RPC主要組成部分
當(dāng)然,上圖是作為RPC的調(diào)用者所觀察到的現(xiàn)象(而實(shí)際情況是客戶(hù)端或多或少的還是需要知道一些調(diào)用RPC的細(xì)節(jié))。但是我們是要講解RPC的基本概念,所以RPC協(xié)議內(nèi)部是怎么回事就要說(shuō)清楚:
-
Client:RPC協(xié)議的調(diào)用方。就像上文所描述的那樣,最理想的情況是RPC Client在完全不知道有RPC框架存在的情況下發(fā)起對(duì)遠(yuǎn)程服務(wù)的調(diào)用。但實(shí)際情況來(lái)說(shuō)Client或多或少的都需要指定RPC框架的一些細(xì)節(jié)。
-
Server:在RPC規(guī)范中,這個(gè)Server并不是提供RPC服務(wù)器IP、端口監(jiān)聽(tīng)的模塊。而是遠(yuǎn)程服務(wù)方法的具體實(shí)現(xiàn)(在JAVA中就是RPC服務(wù)接口的具體實(shí)現(xiàn))。其中的代碼是最普通的和業(yè)務(wù)相關(guān)的代碼,甚至其接口實(shí)現(xiàn)類(lèi)本身都不知道將被某一個(gè)RPC遠(yuǎn)程客戶(hù)端調(diào)用。
-
Stub/Proxy:RPC代理存在于客戶(hù)端,因?yàn)橐獙?shí)現(xiàn)客戶(hù)端對(duì)RPC框架“透明”調(diào)用,那么客戶(hù)端不可能自行去管理消息格式、不可能自己去管理網(wǎng)絡(luò)傳輸協(xié)議,也不可能自己去判斷調(diào)用過(guò)程是否有異常。這一切工作在客戶(hù)端都是交給RPC框架中的“代理”層來(lái)處理的。
-
Message Protocol:在上文我們已經(jīng)說(shuō)到,一次完整的client-server的交互肯定是攜帶某種兩端都能識(shí)別的,共同約定的消息格式。RPC的消息管理層專(zhuān)門(mén)對(duì)網(wǎng)絡(luò)傳輸所承載的消息信息進(jìn)行編碼和解碼操作。目前流行的技術(shù)趨勢(shì)是不同的RPC實(shí)現(xiàn),為了加強(qiáng)自身框架的效率都有一套(或者幾套)私有的消息格式。
-
Transfer/Network Protocol:傳輸協(xié)議層負(fù)責(zé)管理RPC框架所使用的網(wǎng)絡(luò)協(xié)議、網(wǎng)絡(luò)IO模型。例如Hessian的傳輸協(xié)議基于HTTP(應(yīng)用層協(xié)議);而Thrift的傳輸協(xié)議基于TCP(傳輸層協(xié)議)。傳輸層還需要統(tǒng)一RPC客戶(hù)端和RPC服務(wù)端所使用的IO模型;
-
Selector/Processor:存在于RPC服務(wù)端,用于服務(wù)器端某一個(gè)RPC接口的實(shí)現(xiàn)的特性(它并不知道自己是一個(gè)將要被RPC提供給第三方系統(tǒng)調(diào)用的服務(wù))。所以在RPC框架中應(yīng)該有一種“負(fù)責(zé)執(zhí)行RPC接口實(shí)現(xiàn)”的角色。包括:管理RPC接口的注冊(cè)、判斷客戶(hù)端的請(qǐng)求權(quán)限、控制接口實(shí)現(xiàn)類(lèi)的執(zhí)行在內(nèi)的各種工作。
-
IDL:實(shí)際上IDL(接口定義語(yǔ)言)并不是RPC實(shí)現(xiàn)中所必須的。但是需要跨語(yǔ)言的RPC框架一定會(huì)有IDL部分的存在。這是因?yàn)橐业揭粋€(gè)各種語(yǔ)言能夠理解的消息結(jié)構(gòu)、接口定義的描述形式。如果您的RPC實(shí)現(xiàn)沒(méi)有考慮跨語(yǔ)言性,那么IDL部分就不需要包括,例如JAVA RMI因?yàn)榫褪菫榱嗽贘AVA語(yǔ)言間進(jìn)行使用,所以JAVA RMI就沒(méi)有相應(yīng)的IDL。
一定要說(shuō)明一點(diǎn),不同的RPC框架實(shí)現(xiàn)都有一定設(shè)計(jì)差異。例如生成Stub的方式不一樣,IDL描述語(yǔ)言不一樣、服務(wù)注冊(cè)的管理方式不一樣、運(yùn)行服務(wù)實(shí)現(xiàn)的方式不一樣、采用的消息格式封裝不一樣、采用的網(wǎng)絡(luò)協(xié)議不一樣。但是基本的思路都是一樣的,上圖中的所列出的要素也都是具有的。
三、影響RPC框架性能的因素
在物理服務(wù)器性能相同的情況下,以下幾個(gè)因素會(huì)對(duì)一款RPC框架的性能產(chǎn)生直接影響:
-
使用的網(wǎng)絡(luò)IO模型:RPC服務(wù)器可以只支持傳統(tǒng)的阻塞式同步IO,也可以做一些改進(jìn)讓RPC服務(wù)器支持非阻塞式同步IO,或者在服務(wù)器上實(shí)現(xiàn)對(duì)多路IO模型的支持。這樣的RPC服務(wù)器的性能在高并發(fā)狀態(tài)下,會(huì)有很大的差別。特別是單位處理性能下對(duì)內(nèi)存、CPU資源的使用率。
-
基于的網(wǎng)絡(luò)協(xié)議:一般來(lái)說(shuō)您可以選擇讓您的RPC使用應(yīng)用層協(xié)議,例如HTTP或者HTTP/2協(xié)議,或者使用TCP協(xié)議,讓您的RPC框架工作在傳輸層。工作在哪一層網(wǎng)絡(luò)上會(huì)對(duì)RPC框架的工作性能產(chǎn)生一定的影響,但是對(duì)RPC最終的性能影響并不大。但是至少?gòu)母鞣N主流的RPC實(shí)現(xiàn)來(lái)看,沒(méi)有采用UDP協(xié)議做為主要的傳輸協(xié)議的。
-
消息封裝格式:選擇或者定義一種消息格式的封裝,要考慮的問(wèn)題包括:消息的易讀性、描述單位內(nèi)容時(shí)的消息體大小、編碼難度、解碼難度、解決半包/粘包問(wèn)題的難易度。當(dāng)然如果您只是想定義一種RPC專(zhuān)用的消息格式,那么消息的易讀性可能不是最需要考慮的。消息封裝格式的設(shè)計(jì)是目前各種RPC框架性能差異的最重要原因,這就是為什么幾乎所有主流的RPC框架都會(huì)設(shè)計(jì)私有的消息封裝格式的原因。dubbo中消息體數(shù)據(jù)包含dubbo版本號(hào)、接口名稱(chēng)、接口版本、方法名稱(chēng)、參數(shù)類(lèi)型列表、參數(shù)、附加信息
-
Schema 和序列化(Schema & Data Serialization):序列化和反序列化,是對(duì)象到二進(jìn)制數(shù)據(jù)的轉(zhuǎn)換,程序是可以理解對(duì)象的,對(duì)象一般含有 schema 或者結(jié)構(gòu),基于這些語(yǔ)義來(lái)做特定的業(yè)務(wù)邏輯處理。考察一個(gè)序列化框架一般會(huì)關(guān)注以下幾點(diǎn):
Encoding format?。是 human readable(是否能直觀看懂 json) 還是 binary(二進(jìn)制)。
Schema declaration?。也叫作契約聲明,基于 IDL,比如 Protocol Buffers/Thrift,還是自描述的,比如 JSON、XML。另外還需要看是否是強(qiáng)類(lèi)型的。
語(yǔ)言平臺(tái)的中立性?。比如 Java 的 Native Serialization 就只能自己玩,而 Protocol Buffers 可以跨各種語(yǔ)言和平臺(tái)。
新老契約的兼容性?。比如 IDL 加了一個(gè)字段,老數(shù)據(jù)是否還可以反序列化成功。
和壓縮算法的契合度?。跑 benchmark (基準(zhǔn))和實(shí)際應(yīng)用都會(huì)結(jié)合各種壓縮算法,例如 gzip、snappy。
性能?。這是最重要的,序列化、反序列化的時(shí)間,序列化后數(shù)據(jù)的字節(jié)大小是考察重點(diǎn)。
序列化方式非常多,常見(jiàn)的有 Protocol Buffers, Avro,Thrift,XML,JSON,MessagePack,Kyro,Hessian,Protostuff,Java Native Serialize,FST 。 -
實(shí)現(xiàn)的服務(wù)處理管理方式:在高并發(fā)請(qǐng)求下,如何管理注冊(cè)的服務(wù)也是一個(gè)性能影響點(diǎn)。您可以讓RPC的Selector/Processor使用單個(gè)線程運(yùn)行服務(wù)的具體實(shí)現(xiàn)(這意味著上一個(gè)客戶(hù)端的請(qǐng)求沒(méi)有處理完,下一個(gè)客戶(hù)端的請(qǐng)求就需要等待)、您也可以為每一個(gè)RPC具體服務(wù)的實(shí)現(xiàn)開(kāi)啟一個(gè)獨(dú)立的線程運(yùn)行(可以一次處理多個(gè)請(qǐng)求,但是操作系統(tǒng)對(duì)于“可運(yùn)行的最大線程數(shù)”是有限制的)、您也可以線程池來(lái)運(yùn)行RPC具體的服務(wù)實(shí)現(xiàn)(目前看來(lái),在單個(gè)服務(wù)節(jié)點(diǎn)的情況下,這種方式是比較好的)、您還可以通過(guò)注冊(cè)代理的方式讓多個(gè)服務(wù)節(jié)點(diǎn)來(lái)運(yùn)行具體的RPC服務(wù)實(shí)現(xiàn)。
四、工業(yè)界的 RPC 框架一覽
4.1、國(guó)內(nèi)
Dubbo 。來(lái)自阿里巴巴?http://dubbo.I/O/
Motan 。新浪微博自用?https://github.com/weibocom/motan
Dubbox 。當(dāng)當(dāng)基于 dubbo 的?https://github.com/dangdangdotcom/dubbox
rpcx 。基于 Golang 的?https://github.com/smallnest/rpcx
4.2、國(guó)外
Thrift from facebook?https://thrift.apache.org
Avro from hadoop?https://avro.apache.org
Finagle by twitter?https://twitter.github.I/O/finagle
gRPC by Google?http://www.grpc.I/O?(Google inside use Stuppy)
Hessian from cuacho?http://hessian.caucho.com
Coral Service inside amazon (not open sourced)
上述列出來(lái)的都是現(xiàn)在互聯(lián)網(wǎng)企業(yè)常用的解決方案,暫時(shí)不考慮傳統(tǒng)的 SOAP,XML-RPC 等。這些是有網(wǎng)絡(luò)資料的,實(shí)際上很多公司內(nèi)部都會(huì)針對(duì)自己的業(yè)務(wù)場(chǎng)景,以及和公司內(nèi)的平臺(tái)相融合(比如監(jiān)控平臺(tái)等),自研一套框架,但是殊途同歸,都逃不掉剛剛上面所列舉的 RPC 的要考慮的各個(gè)部分。
五、如何選擇RPC框架
選擇一個(gè)rpc框架會(huì)基于多方面的考慮: 框架特性、性能、成熟度、技術(shù)支持、社區(qū)活躍度等多個(gè)方面。最重要一點(diǎn),這也是往往很多技術(shù)人員進(jìn)入的誤區(qū),“對(duì)于技術(shù),不要為了使用而使用,用最簡(jiǎn)單合適的技術(shù)實(shí)現(xiàn)解決問(wèn)題才是正道”。架構(gòu)是服務(wù)于業(yè)務(wù)的,能快速方便的滿足業(yè)務(wù)需求的架構(gòu)才是好的架構(gòu)。沒(méi)有最好的,只有適合自己的。
來(lái)源:https://blog.csdn.net/yjp198713/article/details/79410521
總結(jié)
以上是生活随笔為你收集整理的RPC框架(一)RPC简介的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: REST是什么?如何实现RESTful?
- 下一篇: 燃气管道材质要求(燃气管道材质)