有了HTTP,為什么還要RPC?
作者:趙客縵胡纓v吳鉤霜雪明
鏈接:https://www.jianshu.com/p/9d42b926d40d
有了HTTP,為什么還要RPC?
RPC:Remote Procedure Call,遠(yuǎn)程過(guò)程調(diào)用
一直以來(lái)都沒(méi)有深究過(guò)RPC和HTTP的區(qū)別,不都是寫一個(gè)服務(wù)然后在客戶端調(diào)用么?

HTTP和RPC最本質(zhì)的區(qū)別,就是 RPC 主要是基于 TCP/IP 協(xié)議的,而 HTTP 服務(wù)主要是基于 HTTP 協(xié)議的。
我們都知道 HTTP 協(xié)議是在傳輸層協(xié)議 TCP 之上的,所以效率來(lái)看的話,RPC 當(dāng)然是要更勝一籌啦!
HTTP和RPC的相同點(diǎn)是,底層通訊都是基于socket,都可以實(shí)現(xiàn)遠(yuǎn)程調(diào)用,都可以實(shí)現(xiàn)服務(wù)調(diào)用服務(wù)
HTTP 的本質(zhì)
首先你要明確 HTTP 是一個(gè)協(xié)議,是一個(gè)超文本傳輸協(xié)議。
HTTP 它是協(xié)議,不是運(yùn)輸通道。
它基于 TCP/IP 來(lái)傳輸文本、圖片、視頻、音頻等。
重點(diǎn)來(lái)了。
HTTP 不提供數(shù)據(jù)包的傳輸功能,也就是數(shù)據(jù)包從瀏覽器到服務(wù)端再來(lái)回的傳輸和它沒(méi)關(guān)系。
這是 TCP/IP 干的。
那 HTTP 有啥用?我們來(lái)分析一波。
我們上網(wǎng)要么就是獲取一些信息來(lái)看,要么就是修改一些信息。
比如你用瀏覽器刷微博就是獲取信息,發(fā)微博就是修改信息。
所以說(shuō)瀏覽器需要告知服務(wù)器它需要什么,這次的請(qǐng)求是要獲取哪些信息?發(fā)怎么樣的微博。
這就涉及到瀏覽器和服務(wù)器之間的通信交互。
而交互就需要一種格式。
像你我之間的談話就用中文,你要突然換成俄語(yǔ)我聽不懂那不就 GG 了。
所以說(shuō) HTTP 它規(guī)定了一種格式,一種通信格式,大家都用這個(gè)格式來(lái)交談。
這樣不論你是什么服務(wù)器、什么瀏覽器都能順利的交流,減少交互的成本。
就像全世界如果都講中文,那我們不就不需要學(xué)英文了,那不就較少交互的成本了。
不像現(xiàn)在我們還得學(xué)英文,不然就看不懂文檔等等。
萬(wàn)一之后俄語(yǔ)又起來(lái)了,咱還得對(duì)接俄文,這交互成本是不是就上來(lái)了。
而網(wǎng)絡(luò)世界還好,咱們現(xiàn)在的 Web 交互基本上就是 HTTP 了。
其實(shí) HTTP 協(xié)議的格式很像我們信封,有個(gè)固定的格式。

左上角寫郵編,右上角貼郵票,然后地址姓名啥的依次來(lái)。
因?yàn)橛?jì)算機(jī)是很死板的,不像我們?nèi)艘粯佑幸环N立體掃描感,所以要規(guī)定先寫頭、再寫尾。
你要是先寫尾,再寫頭計(jì)算機(jī)就認(rèn)不出來(lái)了。
所以 HTTP 就規(guī)定了請(qǐng)求先搞請(qǐng)求行、再搞請(qǐng)求報(bào)頭、再搞請(qǐng)求體。
響應(yīng)就狀態(tài)行、響應(yīng)報(bào)頭、響應(yīng)體。

所以 HTTP 的本質(zhì)是什么?
就是客戶端和服務(wù)端約定好的一種通信格式。
HTTP 和 RPC 的關(guān)系
HTTP 和 RPC 其實(shí)是兩個(gè)維度的東西, HTTP 指的是通信協(xié)議。
而 RPC 則是遠(yuǎn)程調(diào)用,其對(duì)應(yīng)的是本地調(diào)用。
RPC 的通信可以用 HTTP 協(xié)議,也可以自定義協(xié)議,是不做約束的。
像之前的單體時(shí)代,我們的 service 調(diào)用就是自己實(shí)現(xiàn)的方法,是本地進(jìn)程內(nèi)的調(diào)用。
public?User?getUserById(Long?id)?{
???????return?userDao.getUserById(id);?//?這叫本地調(diào)用
????}
現(xiàn)在都是微服務(wù)了,根據(jù)業(yè)務(wù)模塊做了不同的拆分,像用戶的服務(wù)不用我這個(gè)小組負(fù)責(zé),我這小組只要寫訂單服務(wù)就行了。
但是我們服務(wù)需要用到用戶的信息,于是我們需要調(diào)用用戶小組的服務(wù),于是代碼變成了以下這種
public?User?getUserById(Long?id)?{
???????return?userConsumer.getUserById(id);?//?這是遠(yuǎn)程調(diào)用,邏輯是用戶小組的服務(wù)實(shí)現(xiàn)的。
????}
可能還有些小伙伴不太清楚,再來(lái)看個(gè)圖。

把之前的用戶實(shí)現(xiàn)拆分出來(lái)弄了一個(gè)用戶服務(wù),訂單相關(guān)的也拆成了訂單服務(wù),都單獨(dú)部署。
這樣訂單相關(guān)的服務(wù)要獲取用戶的信息就需要遠(yuǎn)程調(diào)用了。
可以看到 RPC 就是通過(guò)網(wǎng)絡(luò)進(jìn)行遠(yuǎn)程調(diào)用,訂單服務(wù)其實(shí)就是客戶端,而用戶服務(wù)是服務(wù)端。
這又涉及到交互了,所以也需要約定一個(gè)格式,至于要不要用 HTTP 這個(gè)格式,就是大家自己看著辦。
至此相信你對(duì) HTTP 是啥也清楚了。
RPC 和 HTTP 的之間的關(guān)系也清楚了。
那為什么要有 RPC?
可能你常聽到什么什么之間是 RPC 調(diào)用的,那你有沒(méi)有想過(guò)為什么要 RPC, 我們直接 WebClient HTTP 調(diào)用不行么?
其實(shí) RPC 調(diào)用是因?yàn)榉?wù)的拆分,或者本身公司內(nèi)部的多個(gè)服務(wù)之間的通信。
服務(wù)的拆分獨(dú)立部署,那服務(wù)間的調(diào)用就必然需要網(wǎng)絡(luò)通信,用 WebClient 調(diào)用當(dāng)然可行,但是比較麻煩。
我們想即使服務(wù)被拆分了但是使用起來(lái)還是和之前本地調(diào)用一樣方便。
所以就出現(xiàn)了 RPC 框架,來(lái)屏蔽這些底層調(diào)用細(xì)節(jié),使得我們編碼上還是和之前本地調(diào)用相差不多。
并且 HTTP 協(xié)議比較的冗余,RPC 都是內(nèi)部調(diào)用所以不需要太考慮通用性,只要公司內(nèi)部保持格式統(tǒng)一即可。
所以可以做各種定制化的協(xié)議來(lái)使得通信更高效。
比如規(guī)定 yes 代表 yes的練級(jí)攻略,你看是不是更高效了,少傳輸?shù)?5 個(gè)字。
就像特殊行動(dòng)的暗號(hào),高效簡(jiǎn)潔!
所以公司內(nèi)部服務(wù)的調(diào)用一般都用 RPC,而 HTTP 的優(yōu)勢(shì)在于通用,大家都認(rèn)可這個(gè)協(xié)議。
所以三方平臺(tái)提供的接口都是通過(guò) HTTP 協(xié)議調(diào)用的。
所以現(xiàn)在知道為什么我們調(diào)用第三方都是 HTTP ,公司內(nèi)部用 RPC 了吧?
上面這段話看起來(lái)仿佛 HTTP 和 RPC 是對(duì)等關(guān)系,不過(guò)相信大家看了之前的解析心里應(yīng)該都有數(shù)了。
下面來(lái)具體說(shuō)一說(shuō) RPC 服務(wù)和 HTTP 服務(wù)的區(qū)別。
OSI 網(wǎng)絡(luò)七層模型
在說(shuō) RPC 和 HTTP 的區(qū)別之前,我覺(jué)的有必要了解一下 OSI 的七層網(wǎng)絡(luò)結(jié)構(gòu)模型(

它可以分為以下幾層:(從上到下)
-
第一層:應(yīng)用層。定義了用于在網(wǎng)絡(luò)中進(jìn)行通信和傳輸數(shù)據(jù)的接口。
-
第二層:表示層。定義不同的系統(tǒng)中數(shù)據(jù)的傳輸格式,編碼和解碼規(guī)范等。
-
第三層:會(huì)話層。管理用戶的會(huì)話,控制用戶間邏輯連接的建立和中斷。
-
第四層:傳輸層。管理著網(wǎng)絡(luò)中的端到端的數(shù)據(jù)傳輸。
-
第五層:網(wǎng)絡(luò)層。定義網(wǎng)絡(luò)設(shè)備間如何傳輸數(shù)據(jù)。
-
第六層:鏈路層。將上面的網(wǎng)絡(luò)層的數(shù)據(jù)包封裝成數(shù)據(jù)幀,便于物理層傳輸。
-
第七層:物理層。這一層主要就是傳輸這些二進(jìn)制數(shù)據(jù)。

實(shí)際應(yīng)用過(guò)程中,五層協(xié)議結(jié)構(gòu)里面是沒(méi)有表示層和會(huì)話層的。應(yīng)該說(shuō)它們和應(yīng)用層合并了。
我們應(yīng)該將重點(diǎn)放在應(yīng)用層和傳輸層這兩個(gè)層面。因?yàn)?HTTP 是應(yīng)用層協(xié)議,而 TCP 是傳輸層協(xié)議。
好,知道了網(wǎng)絡(luò)的分層模型以后我們可以更好地理解為什么 RPC 服務(wù)相比 HTTP 服務(wù)要 Nice 一些!
RPC 服務(wù)
從三個(gè)角度來(lái)介紹 RPC 服務(wù),分別是:
-
RPC 架構(gòu)
-
同步異步調(diào)用
-
流行的 RPC 框架
RPC 架構(gòu)
先說(shuō)說(shuō) RPC 服務(wù)的基本架構(gòu)吧。我們可以很清楚地看到,一個(gè)完整的 RPC 架構(gòu)里面包含了四個(gè)核心的組件。
分別是:
-
Client
-
Server
-
Client Stub
-
Server Stub(這個(gè)Stub大家可以理解為存根)

分別說(shuō)說(shuō)這幾個(gè)組件:
-
客戶端(Client),服務(wù)的調(diào)用方。
-
服務(wù)端(Server),真正的服務(wù)提供者。
-
客戶端存根,存放服務(wù)端的地址消息,再將客戶端的請(qǐng)求參數(shù)打包成網(wǎng)絡(luò)消息,然后通過(guò)網(wǎng)絡(luò)遠(yuǎn)程發(fā)送給服務(wù)方。微信搜索公眾號(hào):Linux技術(shù)迷,回復(fù):linux 領(lǐng)取資料 。
-
服務(wù)端存根,接收客戶端發(fā)送過(guò)來(lái)的消息,將消息解包,并調(diào)用本地的方法。
RPC 主要是用在大型企業(yè)里面,因?yàn)榇笮推髽I(yè)里面系統(tǒng)繁多,業(yè)務(wù)線復(fù)雜,而且效率優(yōu)勢(shì)非常重要的一塊,這個(gè)時(shí)候 RPC 的優(yōu)勢(shì)就比較明顯了。

比如我們有一個(gè)處理訂單的系統(tǒng)服務(wù),先聲明它的所有的接口,然后將整個(gè)項(xiàng)目打包,服務(wù)端這邊引入,然后實(shí)現(xiàn)相應(yīng)的功能,客戶端這邊也只需要引入就可以調(diào)用了。
為什么這么做?
主要是為了減少客戶端這邊的包大小,因?yàn)槊恳淮未虬l(fā)布的時(shí)候,包太多總是會(huì)影響效率。
另外也是將客戶端和服務(wù)端解耦,提高代碼的可移植性。
同步調(diào)用與異步調(diào)用
什么是同步調(diào)用?什么是異步調(diào)用?
同步調(diào)用就是客戶端等待調(diào)用執(zhí)行完成并返回結(jié)果。
異步調(diào)用就是客戶端不等待調(diào)用執(zhí)行完成返回結(jié)果,不過(guò)依然可以通過(guò)回調(diào)函數(shù)等接收到返回結(jié)果的通知。如果客戶端并不關(guān)心結(jié)果,則可以變成一個(gè)單向的調(diào)用。
流行的 RPC 框架
目前流行的開源 RPC 框架還是比較多的。下面重點(diǎn)介紹三種:
①gRPC 是 Google 最近公布的開源軟件,基于最新的 HTTP2.0 協(xié)議,并支持常見(jiàn)的眾多編程語(yǔ)言。
我們知道 HTTP2.0 是基于二進(jìn)制的 HTTP 協(xié)議升級(jí)版本,目前各大瀏覽器都在快馬加鞭的加以支持。
這個(gè) RPC 框架是基于 HTTP 協(xié)議實(shí)現(xiàn)的,底層使用到了 Netty 框架的支持。
②Thrift 是 Facebook 的一個(gè)開源項(xiàng)目,主要是一個(gè)跨語(yǔ)言的服務(wù)開發(fā)框架。它有一個(gè)代碼生成器來(lái)對(duì)它所定義的 IDL 定義文件自動(dòng)生成服務(wù)代碼框架。
用戶只要在其之前進(jìn)行二次開發(fā)就行,對(duì)于底層的 RPC 通訊等都是透明的。不過(guò)這個(gè)對(duì)于用戶來(lái)說(shuō)的話需要學(xué)習(xí)特定領(lǐng)域語(yǔ)言這個(gè)特性,還是有一定成本的。
③Dubbo 是阿里集團(tuán)開源的一個(gè)極為出名的 RPC 框架,在很多互聯(lián)網(wǎng)公司和企業(yè)應(yīng)用中廣泛使用。協(xié)議和序列化框架都可以插拔是及其鮮明的特色。
HTTP 服務(wù)
通常,我們的開發(fā)模式一直定性為 HTTP 接口開發(fā),也就是我們常說(shuō)的 RESTful 風(fēng)格的服務(wù)接口。
的確,對(duì)于在接口不多、系統(tǒng)與系統(tǒng)交互較少的情況下,解決信息孤島初期常使用的一種通信手段;優(yōu)點(diǎn)就是簡(jiǎn)單、直接、開發(fā)方便。
利用現(xiàn)成的 HTTP 協(xié)議進(jìn)行傳輸。
平時(shí)的工作主要就是進(jìn)行接口的開發(fā),還要寫一大份接口文檔,嚴(yán)格地標(biāo)明輸入輸出是什么?說(shuō)清楚每一個(gè)接口的請(qǐng)求方法,以及請(qǐng)求參數(shù)需要注意的事項(xiàng)等。

比如下面這個(gè)例子:
POST?http://www.httpexample.com/restful/buyer/info/shar
接口可能返回一個(gè) JSON 字符串或者是 XML 文檔。然后客戶端再去處理這個(gè)返回的信息,從而可以比較快速地進(jìn)行開發(fā)。
但是對(duì)于大型企業(yè)來(lái)說(shuō),內(nèi)部子系統(tǒng)較多、接口非常多的情況下,RPC 框架的好處就顯示出來(lái)了,首先就是長(zhǎng)鏈接,不必每次通信都要像 HTTP 一樣去 3 次握手什么的,減少了網(wǎng)絡(luò)開銷。
其次就是 RPC 框架一般都有注冊(cè)中心,有豐富的監(jiān)控管理;發(fā)布、下線接口、動(dòng)態(tài)擴(kuò)展等,對(duì)調(diào)用方來(lái)說(shuō)是無(wú)感知、統(tǒng)一化的操作。
小結(jié)
RPC 服務(wù)和 HTTP 服務(wù)還是存在很多的不同點(diǎn)的,一般來(lái)說(shuō),RPC 服務(wù)主要是針對(duì)大型企業(yè)的,而 HTTP 服務(wù)主要是針對(duì)小企業(yè)的,因?yàn)?RPC 效率更高,而 HTTP 服務(wù)開發(fā)迭代會(huì)更快。
很多RPC框架包含了重試機(jī)制,路由策略,負(fù)載均衡策略,高可用策略,流量控制策略等等。如果應(yīng)用進(jìn)程之間只使用HTTP協(xié)議通信,顯然是無(wú)法完成上述功能的。
總之,選用什么樣的框架不是按照市場(chǎng)上流行什么而決定的,而是要對(duì)整個(gè)項(xiàng)目進(jìn)行完整地評(píng)估,從而在仔細(xì)比較兩種開發(fā)框架對(duì)于整個(gè)項(xiàng)目的影響,最后再?zèng)Q定什么才是最適合這個(gè)項(xiàng)目的。
一定不要為了使用 RPC 而每個(gè)項(xiàng)目都用 RPC,而是要因地制宜,具體情況具體分析。
--完--
讀到這里說(shuō)明你
喜歡
本公眾號(hào)的文章,歡迎?
置頂(標(biāo)星)
本公眾號(hào)?架構(gòu)師指南,這樣就可以第一時(shí)間獲取推送了~
在本公眾號(hào)?架構(gòu)師指南,后臺(tái)回復(fù):
架構(gòu)師
,領(lǐng)取2T學(xué)習(xí)資料?!
推
薦
閱
讀
1.?后端架構(gòu)師技術(shù)大全(69個(gè)點(diǎn))
2.?架構(gòu)師如何設(shè)計(jì)權(quán)限系統(tǒng)?
3.
?我怎么才能成為一個(gè)架構(gòu)師 ?
4.?架構(gòu)師從0搭建一套訂單系統(tǒng)!
