RPC框架
此篇文章主要對有關RPC框架理論概念的整理總結,現(xiàn)有的技術都是為了實現(xiàn)理論而誕生出來的惕艳,無論多么花哨的技術無非是更好的實現(xiàn)了提出的理論搞隐,希望此篇文章能對你理解RPC、更好的去描述RPC有幫助远搪。
背景
- 隨著企業(yè) IT 服務的不斷發(fā)展劣纲,單臺服務器逐漸無法承受用戶日益增長的請求壓力時,就需要多臺服務器聯(lián)合起來構成「服務集群」共同對外提供服務谁鳍。
- 同時業(yè)務服務會隨著產(chǎn)品需求的增多越來越腫癞季,架構上必須進行服務拆分,一個完整的大型服務會被打散成很多很多獨立的小服務倘潜,每個小服務會由獨立的進程去管理來對外提供服務绷柒,這就是「微服務」。
- 當用戶的請求到來時涮因,我們需要將用戶的請求分散到多個服務去各自處理废睦,然后又需要將這些子服務的結果匯總起來呈現(xiàn)給用戶。那么服務之間該使用何種方式進行交互就是需要解決的核心問題蕊退。RPC 就是為解決服務之間信息交互而發(fā)明和存在的郊楣。
什么是 RPC ?
- RPC (Remote Procedure Call)即遠程過程調(diào)用瓤荔,是分布式系統(tǒng)常見的一種通信方法净蚤。它允許程序調(diào)用另一個地址空間(通常是共享網(wǎng)絡的另一臺機器上)的過程或函數(shù),而不用程序員顯式編碼這個遠程調(diào)用的細節(jié)输硝。
- 除 RPC 之外今瀑,常見的多系統(tǒng)數(shù)據(jù)交互方案還有分布式消息隊列、HTTP 請求調(diào)用、數(shù)據(jù)庫和分布式緩存等橘荠。
- 其中 RPC 和 HTTP 調(diào)用是沒有經(jīng)過中間件的屿附,它們是端到端系統(tǒng)的直接數(shù)據(jù)交互。
簡單的說
- RPC就是從一臺機器(客戶端)上通過參數(shù)傳遞的方式調(diào)用另一臺機器(服務器)上的一個函數(shù)或方法(可以統(tǒng)稱為服務)并得到返回的結果哥童。
- RPC會隱藏底層的通訊細節(jié)(不需要直接處理Socket通訊或Http通訊)挺份。
- 客戶端發(fā)起請求,服務器返回響應(類似于Http的工作方式)RPC在使用形式上像調(diào)用本地函數(shù)(或方法)一樣去調(diào)用遠程的函數(shù)(或方法)贮懈。
為什么我們要用RPC?
RPC 的主要目標是讓構建分布式應用更容易匀泊,在提供強大的遠程調(diào)用能力時不損失本地調(diào)用的語義簡潔性。為實現(xiàn)該目標朵你,RPC 框架需提供一種透明調(diào)用機制讓使用者不必顯式的區(qū)分本地調(diào)用和遠程調(diào)用各聘。
RPC需要解決的三個問題
RPC要達到的目標:遠程調(diào)用時,要能夠像本地調(diào)用一樣方便抡医,讓調(diào)用者感知不到遠程調(diào)用的邏輯躲因。
- Call ID映射。我們怎么告訴遠程機器我們要調(diào)用哪個函數(shù)呢忌傻?在本地調(diào)用中大脉,函數(shù)體是直接通過函數(shù)指針來指定的,我們調(diào)用具體函數(shù)芯勘,編譯器就自動幫我們調(diào)用它相應的函數(shù)指針箱靴。但是在遠程調(diào)用中,是無法調(diào)用函數(shù)指針的荷愕,因為兩個進程的地址空間是完全不一樣衡怀。所以,在RPC中安疗,所有的函數(shù)都必須有自己的一個ID抛杨。這個ID在所有進程中都是唯一確定的〖隼啵客戶端在做遠程過程調(diào)用時怖现,必須附上這個ID。然后我們還需要在客戶端和服務端分別維護一個 {函數(shù) <--> Call ID} 的對應表玉罐。兩者的表不一定需要完全相同屈嗤,但相同的函數(shù)對應的Call ID必須相同。當客戶端需要進行遠程調(diào)用時吊输,它就查一下這個表饶号,找出相應的Call ID,然后把它傳給服務端季蚂,服務端也通過查表茫船,來確定客戶端需要調(diào)用的函數(shù)琅束,然后執(zhí)行相應函數(shù)的代碼。
- 序列化和反序列化算谈∩鳎客戶端怎么把參數(shù)值傳給遠程的函數(shù)呢?在本地調(diào)用中然眼,我們只需要把參數(shù)壓到棧里艾船,然后讓函數(shù)自己去棧里讀就行。但是在遠程過程調(diào)用時罪治,客戶端跟服務端是不同的進程丽声,不能通過內(nèi)存來傳遞參數(shù)。甚至有時候客戶端和服務端使用的都不是同一種語言(比如服務端用C++觉义,客戶端用Java或者Python)。這時候就需要客戶端把參數(shù)先轉(zhuǎn)成一個字節(jié)流浴井,傳給服務端后晒骇,再把字節(jié)流轉(zhuǎn)成自己能讀取的格式。這個過程叫序列化和反序列化磺浙。同理洪囤,從服務端返回的值也需要序列化反序列化的過程。
- 網(wǎng)絡傳輸撕氧。遠程調(diào)用往往是基于網(wǎng)絡的瘤缩,客戶端和服務端是通過網(wǎng)絡連接的。所有的數(shù)據(jù)都需要通過網(wǎng)絡傳輸伦泥,因此就需要有一個網(wǎng)絡傳輸層剥啤。網(wǎng)絡傳輸層需要把Call ID和序列化后的參數(shù)字節(jié)流傳給服務端,然后再把序列化后的調(diào)用結果傳回客戶端不脯。只要能完成這兩者的府怯,都可以作為傳輸層使用。因此防楷,它所使用的協(xié)議其實是不限的牺丙,能完成傳輸就行。盡管大部分RPC框架都使用TCP協(xié)議复局,但其實UDP也可以冲簿,而gRPC干脆就用了HTTP2。Java的Netty也屬于這層的東西亿昏。
實現(xiàn)高可用RPC框架需要考慮到的問題
要實現(xiàn)一個RPC不算難峦剔,難的是實現(xiàn)一個高性能高可靠的RPC框架
- 既然系統(tǒng)采用分布式架構,那一個服務勢必會有多個實例龙优,要解決如何獲取實例的問題羊异。所以需要一個服務注冊中心事秀,比如在Dubbo中,就可以使用Zookeeper作為注冊中心野舶,在調(diào)用時易迹,從Zookeeper獲取服務的實例列表,再從中選擇一個進行調(diào)用平道;
- 如何選擇實例呢睹欲?就要考慮負載均衡,例如dubbo提供了4種負載均衡策略一屋;
- 如果每次都去注冊中心查詢列表窘疮,效率很低,那么就要加緩存冀墨;
- 客戶端總不能每次調(diào)用完都等著服務端返回數(shù)據(jù)闸衫,所以就要支持異步調(diào)用;
- 服務端的接口修改了诽嘉,老的接口還有人在用蔚出,這就需要版本控制;
- 服務端總不能每次接到請求都馬上啟動一個線程去處理虫腋,于是就需要線程池骄酗;
理論結構模型
RPC 服務端通過RpcServer去導出(export)遠程接口方法,而客戶端通過RpcClient去導入(import)遠程接口方法悦冀∏鞣客戶端像調(diào)用本地方法一樣去調(diào)用遠程接口方法,RPC 框架提供接口的代理實現(xiàn)盒蟆,實際的調(diào)用將委托給代理RpcProxy踏烙。代理封裝調(diào)用信息并將調(diào)用轉(zhuǎn)交給RpcInvoker去實際執(zhí)行。在客戶端的RpcInvoker通過連接器RpcConnector去維持與服務端的通道RpcChannel茁影,并使用RpcProtocol執(zhí)行協(xié)議編碼(encode)并將編碼后的請求消息通過通道發(fā)送給服務端宙帝。
RPC 服務端接收器RpcAcceptor接收客戶端的調(diào)用請求,同樣使用RpcProtocol執(zhí)行協(xié)議解碼(decode)募闲。
解碼后的調(diào)用信息傳遞給RpcProcessor去控制處理調(diào)用過程步脓,最后再委托調(diào)用給RpcInvoker去實際執(zhí)行并返回調(diào)用結果。
組 件 | 功 能 |
---|---|
PrcServer | 負責導出(export)遠程接口 |
RpcClient | 負責導入(import)遠程接口的代理實現(xiàn) |
RpcProxy | 遠程接口的代理實現(xiàn) |
RpcInvoker | 客戶端:負責編碼調(diào)用信息和發(fā)送調(diào)用請求到服務端并等待調(diào)用結果返回;服務端:負責調(diào)用服務端接口的具體實現(xiàn)并返回調(diào)用結果 |
RpcProtocol | 負責協(xié)議編/解碼 |
RpcConnector | 負責維持客戶端和服務端的連接通道和發(fā)送數(shù)據(jù)到服務端 |
RpcAcceptor | 負責接收客戶端請求并返回請求結果 |
RpcProcessor | 負責在服務端控制調(diào)用過程浩螺,包括管理調(diào)用線程池靴患、超時時間等 |
RpcChannel | 數(shù)據(jù)傳輸通道 |
———————— | - |
主流的RPC框架
服務治理型
- dubbo:是阿里巴巴公司開源的一個Java高性能優(yōu)秀的服務框架,使得應用可通過高性能的 RPC 實現(xiàn)服務的輸出和輸入功能要出,可以和 Spring框架無縫集成鸳君。dubbo 已經(jīng)與12年年底停止維護升級。
- dubbox:是當當團隊基于dubbo升級的一個版本患蹂。是一個分布式的服務架構或颊,可直接用于生產(chǎn)環(huán)境作為SOA服務框架砸紊。dubbox資源鏈接
- motan:是新浪微博開源的一個Java框架。它誕生的比較晚囱挑,起于2013年醉顽,2016年5月開源。Motan 在微博平臺中已經(jīng)廣泛應用平挑,每天為數(shù)百個服務完成近千億次的調(diào)用魔种。motan資源鏈接
多語言型
- gRPC:是Google開發(fā)的高性能吧彪、通用的開源RPC框架,其由Google主要面向移動應用開發(fā)并基于HTTP/2協(xié)議標準而設計涂乌,基于ProtoBuf(Protocol Buffers)序列化協(xié)議開發(fā)会傲,且支持眾多開發(fā)語言序矩。本身它不是分布式的秧均,所以要實現(xiàn)上面的框架的功能需要進一步的開發(fā)锉罐。gRPC資源鏈接
- thrift:是Apache的一個跨語言的高性能的服務框架,也得到了廣泛的應用赏枚。Thrift文檔
參考文獻
https://www.zhihu.com/question/25536695/answer/221638079