淺談RPC那些事兒[1]
掃描二維碼
隨時隨地手機(jī)看文章
1 前言
今天來和大家一起學(xué)習(xí)一下RPC,還是要先聲明篇幅所限,本文不會深入展開,所以本文是淺談。
還是老規(guī)矩,秉承 "最基礎(chǔ)的也是最重要的,最重要的也是最簡單的",不搞那么花哨。
能讓對這個事情一無所知但是有相關(guān)經(jīng)驗的人員迅速切入重點,掌握輪廓是一種重要的能力,知道別人會困在哪里,哪些是必要的更是一種思維方式。
一個好的廚師應(yīng)該也是一個美食家,如果你還是個業(yè)務(wù)仔,但是想成為架構(gòu)師,不要著急,懂業(yè)務(wù)才更懂架構(gòu),架構(gòu)是為業(yè)務(wù)服務(wù)的,紙上談兵的架構(gòu)師也造不出好輪子。
個人認(rèn)為:抽象問題和拆解問題是做好架構(gòu)和業(yè)務(wù)的重要能力,在日常工作中要注意兩方面的培養(yǎng)。
通過本文你將了解到以下內(nèi)容:
-
什么是RPC和為什么需要它 -
RPC的重要組件 -
常見RPC框架和各自特點
廢話不說,開車開車!
圖來自網(wǎng)絡(luò): 好奇號火星車
2 什么是RPC以及為什么需要它
RPC 是1984年代由 Andrew D. Birrell & Bruce Jay Nelson 提出的,所以并不是最近的概念,在二位大神的論文 "Implementing Remote Procedure Calls" :
Implementing Remote Procedure Calls http://pages.cs.wisc.edu/~sschang/OS-Qual/distOS/RPC.htm
設(shè)計目標(biāo):
Make distributed computing easy: let the programmer focus on fundamental difficulty of distributed computing: timing, independent failure of components.
Make RPC communication highly efficient: don't distort program by making programmer avoid communication due to its slowness
Make the semantics of RPC as powerful as possible without loss of simplicity or efficiency
Provide secure communication
簡單概括就是讓分布式系統(tǒng)更加簡單,讓開發(fā)人員把精力放到業(yè)務(wù)上,并且提供高效安全的通信。
再來看看比較常見的解釋,了解下RPC是啥:
RPC(Remote Procedure Call)遠(yuǎn)程過程調(diào)用,它是一種通過網(wǎng)絡(luò)從遠(yuǎn)程計算機(jī)程序上請求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。也就是說兩臺服務(wù)器A,B,一個應(yīng)用部署在A服務(wù)器上,想要調(diào)用B服務(wù)器上應(yīng)用提供的方法,由于不在一個內(nèi)存空間,不能直接調(diào)用,需要通過網(wǎng)絡(luò)來表達(dá)調(diào)用的語義和傳達(dá)調(diào)用的數(shù)據(jù)。
大白話理解這段話就是說:RPC讓你用別人家的東西就像自己家的一樣。
聽得我似懂非懂,于是我不得不問幾個問題:
-
為啥要用別人家的東西(請求其他服務(wù)) -
我怎么可以借到別人家的東西(其他服務(wù)調(diào)用) -
要是借用的話哪種形式更好(確定一個合適的調(diào)用方法) -
怎么讓我用別人東西像自己的一樣(屏蔽底層細(xì)節(jié)透明通信)
2.1 為什么要請求其他服務(wù)
典型的B/S模型或者C/S模型都是客戶端要調(diào)用服務(wù)端接口來獲取數(shù)據(jù)和結(jié)果,這種屬于外部調(diào)用。
區(qū)別于外部調(diào)用,內(nèi)部系統(tǒng)隨著業(yè)務(wù)規(guī)模的擴(kuò)大,出現(xiàn)了分布式和微服務(wù),簡單說就是把一個龐大的業(yè)務(wù)拆分成很多子服務(wù),并且每個子服務(wù)都部署在很多獨(dú)立分布的機(jī)器上,從而形成一個龐大的內(nèi)部系統(tǒng)。
生活也是如此,自給自足的農(nóng)耕經(jīng)濟(jì)早已經(jīng)過去,不同的社會分工有不同的公司團(tuán)體機(jī)構(gòu),我們要想完成自己的日常就難免和其他單位實體進(jìn)行交互。
還是舉一個例子:比如我們用QQ音樂聽歌,感興趣的歌曲會做成歌單,當(dāng)手機(jī)端用戶先用手機(jī)號/郵箱/第三方賬號等進(jìn)行登陸,登錄之后進(jìn)入的自己主頁,拉取自己喜歡的歌曲歌單,最后點擊播放,這個過程就涉及到多個服務(wù)的相互調(diào)用,如圖:
龐大的單體程序好像逐漸沒有市場了,取而代之的是拆分之后的諸多獨(dú)立功能的服務(wù),它們之間必然存在相互調(diào)用來實現(xiàn)一個綜合的功能。
2.2 如何調(diào)用其他服務(wù)
在日常業(yè)務(wù)中我們可以把功能封裝成靜態(tài)庫、動態(tài)庫、sdk、獨(dú)立服務(wù)等,最常見也最方便的還是http這種形式的調(diào)用。
http服務(wù)把需要提供的服務(wù)暴露成接口,使用方直接按約定的http方法和uri進(jìn)行數(shù)據(jù)交互。
我們都知道http協(xié)議是應(yīng)用層協(xié)議,是個非常標(biāo)準(zhǔn)的協(xié)議,在http協(xié)議之下還有網(wǎng)絡(luò)層、傳輸層、數(shù)據(jù)鏈路層等,一個數(shù)據(jù)包packet除了凈荷payload之外還有很多header,由于標(biāo)準(zhǔn)和通用性的設(shè)計目標(biāo)也使得http一次數(shù)據(jù)交互真正傳輸?shù)膒ayload只是其中一部分。
圖來自網(wǎng)絡(luò):http數(shù)據(jù)包格式
http是我們用的最多最熟悉的交互模式,在系統(tǒng)內(nèi)部各個服務(wù)之間接口較少,交互不多的情況下工作得還不錯。
在內(nèi)部系統(tǒng)調(diào)用很復(fù)雜的前提下,http調(diào)用的效率和安全性就不那么理想了,更重要的是面對眾多的服務(wù)我們需要的不僅僅是一個通信方式,而是一個內(nèi)部服務(wù)的管理系統(tǒng),這也就是我們今天說的RPC框架,注意RPC是一種模式策略和框架,并不是單純的通信協(xié)議。
2.3 實現(xiàn)遠(yuǎn)程調(diào)用的一些思路
前面說了RPC遠(yuǎn)程過程調(diào)用就是讓服務(wù)A像調(diào)用本地功能一樣調(diào)用遠(yuǎn)端的服務(wù)B上的功能,不要把這個事情想的太懸乎,想想我們本地調(diào)用時需要哪些東西:確定的類或函數(shù)、類或函數(shù)的參數(shù)、類或函數(shù)的返回值。
遠(yuǎn)程調(diào)用肯定也不會缺少這三要素,唯一的區(qū)別在于這三要素是要被傳輸過去的,這其中就涉及協(xié)議編碼和解碼的過程。
機(jī)器10.1.1.1上部署了服務(wù)A,機(jī)器10.1.1.2上部署了服務(wù)B,并且服務(wù)B上有一個add函數(shù),int add(int a,int b),參數(shù)是兩個int 返回值是int。
這樣服務(wù)A需要通過網(wǎng)絡(luò)傳輸來告訴服務(wù)B,它想要add函數(shù),傳入的兩個參數(shù)分別是3和5,返回的結(jié)果放在result里面就可以。
傳輸?shù)膱笪睦锩姘凑占s定的協(xié)議格式給出了函數(shù)名和參數(shù),大致這樣:
上述的編碼只是一種舉例不代表實際應(yīng)用,旨在說明本地調(diào)用和遠(yuǎn)程調(diào)用的唯一區(qū)別就是傳輸基本要素的方式不同,不要想的太復(fù)雜。
為了提高傳輸效率可以進(jìn)行二進(jìn)制編碼,比如protobuf這種。當(dāng)然還有其他問題,就不再詳細(xì)展開了,這些都是我們在設(shè)計一個RPC框架時需要考慮的點。
2.4 關(guān)于http和RPC的一些辯論
http和rpc是兩個很容易混淆的概念,最開始接觸rpc的時候,我就在想有http了為什么還要用rpc? 在知乎上看到了這個很有趣的問題:
在知乎上有個很好的問題:既然有http請求,為什么還要用rpc? 詳情戳:https://www.zhihu.com/question/41609070
其中一個大佬的回答感覺很有意思:
這個問題的諸多回答其實都表達(dá)了一個重要觀點:RPC是一種編程模式和概念,并不是非常具體的一種技術(shù),并且和http沒有明確的沖突,http可以作為RPC傳輸協(xié)議,更重要的是RPC是一種內(nèi)部服務(wù)框架,可以涉及服務(wù)注冊、服務(wù)治理、服務(wù)發(fā)現(xiàn)、熔斷機(jī)制、負(fù)載均衡等。
3.典型的RPC框架組件
前面提到了rpc不是簡單的一種協(xié)議或者技術(shù),而是一種模式和框架,其典型的組成,如圖:
圖來自網(wǎng)絡(luò):rpc典型組成
RPC協(xié)議模塊是很重要的部分,這部分也是前面提到的服務(wù)A調(diào)用服務(wù)B時傳輸報文的過程,如圖:
圖來自網(wǎng)絡(luò):rpc協(xié)議組成
其中的序列化和反序列化定義:
序列化:將數(shù)據(jù)結(jié)構(gòu)或?qū)ο筠D(zhuǎn)換成二進(jìn)制串的過程。
反序列化:將序列化中所生成的二進(jìn)制串轉(zhuǎn)換成數(shù)據(jù)結(jié)構(gòu)或者對象的過程。
在網(wǎng)絡(luò)消息傳輸中可以基于TCP、UDP、http來實現(xiàn),各自都有各自的特點:
基于 TCP 實現(xiàn)的 RPC 調(diào)用,能夠靈活對協(xié)議字段進(jìn)行定制,減少網(wǎng)絡(luò)開銷提高性能,實現(xiàn)更大的吞吐量和并發(fā)數(shù),但要關(guān)注底層細(xì)節(jié),在進(jìn)行數(shù)據(jù)解析時更加復(fù)雜一些。
基于 HTTP 實現(xiàn)的 RPC 可以使用 JSON 和 XML 格式的請求或響應(yīng)數(shù)據(jù),解析工具很成熟,在其上進(jìn)行二次開發(fā)會非常便捷和簡單。但是 HTTP 是上層協(xié)議,所占用的字節(jié)數(shù)會比使用 TCP 協(xié)議傳輸所占用的字節(jié)數(shù)更高。
對于其他部分,本文不再展開。
4.常見的RPC框架和各自特點
Dubbo 是阿里巴巴公司開源的一個Java高性能優(yōu)秀的服務(wù)框架,使得應(yīng)用可通過高性能的 RPC 實現(xiàn)服務(wù)的輸出和輸入功能,可以和 Spring框架無縫集成。
Motan是新浪微博開源的一個Java 框架。它誕生的比較晚,起于2013年,2016年5月開源。Motan 在微博平臺中已經(jīng)廣泛應(yīng)用,每天為數(shù)百個服務(wù)完成近千億次的調(diào)用。
rpcx是Go語言生態(tài)圈的Dubbo, 比Dubbo更輕量實現(xiàn)了Dubbo的許多特性,借助于Go語言優(yōu)秀的并發(fā)特性和簡潔語法,可以使用較少的代碼實現(xiàn)分布式的RPC服務(wù)。
gRPC是Google開發(fā)的高性能、通用的開源RPC框架,其由Google主要面向移動應(yīng)用開發(fā)并基于HTTP/2協(xié)議標(biāo)準(zhǔn)而設(shè)計,基于ProtoBuf(Protocol Buffers)序列化協(xié)議開發(fā),且支持眾多開發(fā)語言。本身它不是分布式的,所以要實現(xiàn)上面的框架的功能需要進(jìn)一步的開發(fā)。
thrift是Apache的一個跨語言的高性能的服務(wù)框架,也得到了廣泛的應(yīng)用,Thrift是Facebook于2007年開發(fā)的,它提供多語言的編譯功能,通過Thrift的IDL來描述接口函數(shù)及數(shù)據(jù)類型,通過Thrift的編譯環(huán)境生成各種語言類型的接口文件。
brpc(baidu-rpc)是百度開發(fā)一款遠(yuǎn)過程調(diào)用網(wǎng)絡(luò)框架。目前該項目已在github上開源,brpc目前被應(yīng)用于百度公司內(nèi)部各種核心業(yè)務(wù)上,其中包括高性能計算和模型訓(xùn)練和各種索引和排序服務(wù),且有超過100萬以上個實例是基于brpc工作的。
Tars 是騰訊根據(jù)內(nèi)部多年使用微服務(wù)架構(gòu)的實踐,總結(jié)而成的開源項目,僅支持 C++ 語言,目前在騰訊內(nèi)部應(yīng)用也非常廣泛。
其中關(guān)于brpc在知乎有個很好的問題,其中有包括大神戈君(brpc主導(dǎo)者)在內(nèi)的多個回答,可以幫助我們快速了解brpc框架:
如何評價百度開源的 RPC 框架 brpc?https://www.zhihu.com/question/65370268
tars和brpc是非常不錯的開源項目,尤其作為C++程序員很推薦閱讀。
后面一定要寫一下gRPC、brpc、tars,先占個坑。
5 巨人的肩膀
https://www.w3cschool.cn/architectroad/architectroad-rpc-framework.html
https://developer.51cto.com/art/201906/597963.htm
https://dubbo.apache.org/zh-cn/blog/rpc-introduction.html
https://colobu.com/2016/09/05/benchmarks-of-popular-rpc-frameworks/
https://cloud.tencent.com/developer/article/1383845
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!