有了HTTP两残,為什么還要RPC?
RPC:Remote Procedure Call把跨,遠(yuǎn)程過程調(diào)用
一直以來都沒有深究過RPC和HTTP的區(qū)別人弓,不都是寫一個(gè)服務(wù)然后在客戶端調(diào)用么?
HTTP和RPC最本質(zhì)的區(qū)別着逐,就是 RPC 主要是基于 TCP/IP 協(xié)議的崔赌,而 HTTP 服務(wù)主要是基于 HTTP 協(xié)議的。
我們都知道 HTTP 協(xié)議是在傳輸層協(xié)議 TCP 之上的滨嘱,所以效率來看的話峰鄙,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 來傳輸文本狭瞎、圖片细移、視頻、音頻等熊锭。
重點(diǎn)來了弧轧。
HTTP 不提供數(shù)據(jù)包的傳輸功能,也就是數(shù)據(jù)包從瀏覽器到服務(wù)端再來回的傳輸和它沒關(guān)系碗殷。
這是 TCP/IP 干的精绎。
那 HTTP 有啥用?我們來分析一波锌妻。
我們上網(wǎng)要么就是獲取一些信息來看代乃,要么就是修改一些信息。
比如你用瀏覽器刷微博就是獲取信息仿粹,發(fā)微博就是修改信息搁吓。
所以說瀏覽器需要告知服務(wù)器它需要什么,這次的請求是要獲取哪些信息吭历?發(fā)怎么樣的微博堕仔。
這就涉及到瀏覽器和服務(wù)器之間的通信交互。
而交互就需要一種格式晌区。
像你我之間的談話就用中文贮预,你要突然換成俄語我聽不懂那不就 GG 了。
所以說 HTTP 它規(guī)定了一種格式契讲,一種通信格式仿吞,大家都用這個(gè)格式來交談。
這樣不論你是什么服務(wù)器捡偏、什么瀏覽器都能順利的交流唤冈,減少交互的成本。
就像全世界如果都講中文银伟,那我們不就不需要學(xué)英文了你虹,那不就較少交互的成本了。
不像現(xiàn)在我們還得學(xué)英文彤避,不然就看不懂文檔等等傅物。
萬一之后俄語又起來了,咱還得對接俄文琉预,這交互成本是不是就上來了董饰。
而網(wǎng)絡(luò)世界還好,咱們現(xiàn)在的 Web 交互基本上就是 HTTP 了。
其實(shí) HTTP 協(xié)議的格式很像我們信封卒暂,有個(gè)固定的格式啄栓。
左上角寫郵編,右上角貼郵票也祠,然后地址姓名啥的依次來昙楚。
因?yàn)橛?jì)算機(jī)是很死板的,不像我們?nèi)艘粯佑幸环N立體掃描感诈嘿,所以要規(guī)定先寫頭堪旧、再寫尾。
你要是先寫尾奖亚,再寫頭計(jì)算機(jī)就認(rèn)不出來了崎场。
所以 HTTP 就規(guī)定了請求先搞請求行、再搞請求報(bào)頭遂蛀、再搞請求體。
響應(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)用芹助,其對應(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)的置侍。
}
可能還有些小伙伴不太清楚,再來看個(gè)圖。
把之前的用戶實(shí)現(xiàn)拆分出來弄了一個(gè)用戶服務(wù)墅垮,訂單相關(guān)的也拆成了訂單服務(wù)惕医,都單獨(dú)部署。
這樣訂單相關(guān)的服務(wù)要獲取用戶的信息就需要遠(yuǎn)程調(diào)用了算色。
可以看到 RPC 就是通過網(wǎng)絡(luò)進(jìn)行遠(yuǎn)程調(diào)用抬伺,訂單服務(wù)其實(shí)就是客戶端,而用戶服務(wù)是服務(wù)端灾梦。
這又涉及到交互了峡钓,所以也需要約定一個(gè)格式,至于要不要用 HTTP 這個(gè)格式若河,就是大家自己看著辦能岩。
至此相信你對 HTTP 是啥也清楚了。
RPC 和 HTTP 的之間的關(guān)系也清楚了萧福。
那為什么要有 RPC拉鹃?
可能你常聽到什么什么之間是 RPC 調(diào)用的,那你有沒有想過為什么要 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ù)被拆分了但是使用起來還是和之前本地調(diào)用一樣方便。
所以就出現(xiàn)了 RPC 框架智润,來屏蔽這些底層調(diào)用細(xì)節(jié)及舍,使得我們編碼上還是和之前本地調(diào)用相差不多。
并且 HTTP 協(xié)議比較的冗余窟绷,RPC 都是內(nèi)部調(diào)用所以不需要太考慮通用性击纬,只要公司內(nèi)部保持格式統(tǒng)一即可。
所以可以做各種定制化的協(xié)議來使得通信更高效钾麸。
比如規(guī)定 yes 代表 yes的練級攻略更振,你看是不是更高效了,少傳輸?shù)?5 個(gè)字饭尝。
就像特殊行動(dòng)的暗號肯腕,高效簡潔!
所以公司內(nèi)部服務(wù)的調(diào)用一般都用 RPC钥平,而 HTTP 的優(yōu)勢在于通用实撒,大家都認(rèn)可這個(gè)協(xié)議姊途。
所以三方平臺提供的接口都是通過 HTTP 協(xié)議調(diào)用的。
所以現(xiàn)在知道為什么我們調(diào)用第三方都是 HTTP 知态,公司內(nèi)部用 RPC 了吧捷兰?
上面這段話看起來仿佛 HTTP 和 RPC 是對等關(guān)系,不過相信大家看了之前的解析心里應(yīng)該都有數(shù)了负敏。
下面來具體說一說 RPC 服務(wù)和 HTTP 服務(wù)的區(qū)別贡茅。
OSI 網(wǎng)絡(luò)七層模型
在說 RPC 和 HTTP 的區(qū)別之前,我覺的有必要了解一下 OSI 的七層網(wǎng)絡(luò)結(jié)構(gòu)模型(
它可以分為以下幾層:(從上到下)
第一層:應(yīng)用層其做。定義了用于在網(wǎng)絡(luò)中進(jìn)行通信和傳輸數(shù)據(jù)的接口顶考。
第二層:表示層。定義不同的系統(tǒng)中數(shù)據(jù)的傳輸格式妖泄,編碼和解碼規(guī)范等驹沿。
第三層:會話層。管理用戶的會話蹈胡,控制用戶間邏輯連接的建立和中斷渊季。
第四層:傳輸層。管理著網(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)用過程中赎懦,五層協(xié)議結(jié)構(gòu)里面是沒有表示層和會話層的雀鹃。應(yīng)該說它們和應(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è)角度來介紹 RPC 服務(wù),分別是:
RPC 架構(gòu)
同步異步調(diào)用
流行的 RPC 框架
RPC 架構(gòu)
先說說 RPC 服務(wù)的基本架構(gòu)吧盲憎。我們可以很清楚地看到嗅骄,一個(gè)完整的 RPC 架構(gòu)里面包含了四個(gè)核心的組件。
分別是:
Client
Server
Client Stub
Server Stub(這個(gè)Stub大家可以理解為存根)
分別說說這幾個(gè)組件:
客戶端(Client)饼疙,服務(wù)的調(diào)用方溺森。
服務(wù)端(Server),真正的服務(wù)提供者。
客戶端存根屏积,存放服務(wù)端的地址消息医窿,再將客戶端的請求參數(shù)打包成網(wǎng)絡(luò)消息,然后通過網(wǎng)絡(luò)遠(yuǎn)程發(fā)送給服務(wù)方炊林。
服務(wù)端存根姥卢,接收客戶端發(fā)送過來的消息,將消息解包铛铁,并調(diào)用本地的方法隔显。
RPC 主要是用在大型企業(yè)里面,因?yàn)榇笮推髽I(yè)里面系統(tǒng)繁多饵逐,業(yè)務(wù)線復(fù)雜括眠,而且效率優(yōu)勢非常重要的一塊,這個(gè)時(shí)候 RPC 的優(yōu)勢就比較明顯了倍权。
比如我們有一個(gè)處理訂單的系統(tǒng)服務(wù)掷豺,先聲明它的所有的接口,然后將整個(gè)項(xiàng)目打包薄声,服務(wù)端這邊引入当船,然后實(shí)現(xiàn)相應(yīng)的功能,客戶端這邊也只需要引入就可以調(diào)用了默辨。
為什么這么做德频?
主要是為了減少客戶端這邊的包大小,因?yàn)槊恳淮未虬l(fā)布的時(shí)候缩幸,包太多總是會影響效率壹置。
另外也是將客戶端和服務(wù)端解耦,提高代碼的可移植性表谊。
同步調(diào)用與異步調(diào)用
什么是同步調(diào)用钞护?什么是異步調(diào)用?
同步調(diào)用就是客戶端等待調(diào)用執(zhí)行完成并返回結(jié)果爆办。
異步調(diào)用就是客戶端不等待調(diào)用執(zhí)行完成返回結(jié)果难咕,不過依然可以通過回調(diào)函數(shù)等接收到返回結(jié)果的通知。如果客戶端并不關(guān)心結(jié)果距辆,則可以變成一個(gè)單向的調(diào)用余佃。
流行的 RPC 框架
目前流行的開源 RPC 框架還是比較多的。下面重點(diǎn)介紹三種:
①gRPC 是 Google 最近公布的開源軟件跨算,基于最新的 HTTP2.0 協(xié)議咙冗,并支持常見的眾多編程語言。
我們知道 HTTP2.0 是基于二進(jìn)制的 HTTP 協(xié)議升級版本漂彤,目前各大瀏覽器都在快馬加鞭的加以支持雾消。
這個(gè) RPC 框架是基于 HTTP 協(xié)議實(shí)現(xiàn)的灾搏,底層使用到了 Netty 框架的支持。
②Thrift 是 Facebook 的一個(gè)開源項(xiàng)目立润,主要是一個(gè)跨語言的服務(wù)開發(fā)框架狂窑。它有一個(gè)代碼生成器來對它所定義的 IDL 定義文件自動(dòng)生成服務(wù)代碼框架。
用戶只要在其之前進(jìn)行二次開發(fā)就行桑腮,對于底層的 RPC 通訊等都是透明的泉哈。不過這個(gè)對于用戶來說的話需要學(xué)習(xí)特定領(lǐng)域語言這個(gè)特性,還是有一定成本的破讨。
③Dubbo 是阿里集團(tuán)開源的一個(gè)極為出名的 RPC 框架丛晦,在很多互聯(lián)網(wǎng)公司和企業(yè)應(yīng)用中廣泛使用。協(xié)議和序列化框架都可以插拔是及其鮮明的特色提陶。
HTTP 服務(wù)
通常烫沙,我們的開發(fā)模式一直定性為 HTTP 接口開發(fā),也就是我們常說的 RESTful 風(fēng)格的服務(wù)接口隙笆。
的確锌蓄,對于在接口不多、系統(tǒng)與系統(tǒng)交互較少的情況下撑柔,解決信息孤島初期常使用的一種通信手段瘸爽;優(yōu)點(diǎn)就是簡單、直接铅忿、開發(fā)方便剪决。
利用現(xiàn)成的 HTTP 協(xié)議進(jìn)行傳輸。
平時(shí)的工作主要就是進(jìn)行接口的開發(fā)檀训,還要寫一大份接口文檔柑潦,嚴(yán)格地標(biāo)明輸入輸出是什么?說清楚每一個(gè)接口的請求方法肢扯,以及請求參數(shù)需要注意的事項(xiàng)等妒茬。
比如下面這個(gè)例子:
POST http://www.httpexample.com/restful/buyer/info/shar
接口可能返回一個(gè) JSON 字符串或者是 XML 文檔担锤。然后客戶端再去處理這個(gè)返回的信息蔚晨,從而可以比較快速地進(jìn)行開發(fā)。
但是對于大型企業(yè)來說肛循,內(nèi)部子系統(tǒng)較多铭腕、接口非常多的情況下,RPC 框架的好處就顯示出來了多糠,首先就是長鏈接累舷,不必每次通信都要像 HTTP 一樣去 3 次握手什么的,減少了網(wǎng)絡(luò)開銷夹孔。
其次就是 RPC 框架一般都有注冊中心被盈,有豐富的監(jiān)控管理析孽;發(fā)布、下線接口只怎、動(dòng)態(tài)擴(kuò)展等袜瞬,對調(diào)用方來說是無感知、統(tǒng)一化的操作身堡。
小結(jié)
RPC 服務(wù)和 HTTP 服務(wù)還是存在很多的不同點(diǎn)的邓尤,一般來說,RPC 服務(wù)主要是針對大型企業(yè)的贴谎,而 HTTP 服務(wù)主要是針對小企業(yè)的汞扎,因?yàn)?RPC 效率更高,而 HTTP 服務(wù)開發(fā)迭代會更快擅这。
很多RPC框架包含了重試機(jī)制澈魄,路由策略,負(fù)載均衡策略蕾哟,高可用策略一忱,流量控制策略等等。 如果應(yīng)用進(jìn)程之間只使用HTTP協(xié)議通信谭确,顯然是無法完成上述功能的帘营。
總之,選用什么樣的框架不是按照市場上流行什么而決定的逐哈,而是要對整個(gè)項(xiàng)目進(jìn)行完整地評估芬迄,從而在仔細(xì)比較兩種開發(fā)框架對于整個(gè)項(xiàng)目的影響,最后再決定什么才是最適合這個(gè)項(xiàng)目的昂秃。
一定不要為了使用 RPC 而每個(gè)項(xiàng)目都用 RPC禀梳,而是要因地制宜,具體情況具體分析肠骆。