大家好,歡迎收看猿話!
RPC就是遠(yuǎn)程過(guò)程調(diào)用,它是一種通過(guò)網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請(qǐng)求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的思想。
原理
一個(gè)完整的RPC主要包括三部分:
- 服務(wù)注冊(cè)中心(Registry),負(fù)責(zé)將本地服務(wù)發(fā)布成遠(yuǎn)程服務(wù),管理遠(yuǎn)程服務(wù),提供給服務(wù)消費(fèi)者使用。
- 服務(wù)提供者(RPC Server),負(fù)責(zé)提供服務(wù)接口定義與服務(wù)實(shí)現(xiàn)類。
- 服務(wù)消費(fèi)者(RPC Client),負(fù)責(zé)通過(guò)遠(yuǎn)程代理對(duì)象調(diào)用遠(yuǎn)程服務(wù)。
服務(wù)提供者(Server)啟動(dòng)后主動(dòng)向服務(wù)注冊(cè)中心(Registry)注冊(cè)機(jī)器IP、端口以及提供的服務(wù)列表;
服務(wù)消費(fèi)者(Client)啟動(dòng)時(shí)向服務(wù)注冊(cè)中心(Registry)獲取服務(wù)提供方地址列表。
服務(wù)注冊(cè)中心(Registry)可實(shí)現(xiàn)負(fù)載均衡和故障切換。
RPC調(diào)用過(guò)程如下圖所示:
(1) 客戶端(Client)以本地調(diào)用方式調(diào)用服務(wù);
(2) 客戶端存根(Client stub)接收到調(diào)用后,負(fù)責(zé)將方法、參數(shù)等組裝成能夠進(jìn)行網(wǎng)絡(luò)傳輸?shù)南Ⅲw(將消息體對(duì)象序列化為二進(jìn)制);
(3) 客戶端通過(guò) Network Service 將消息發(fā)送到服務(wù)端;
(4) 服務(wù)端存根(Server stub)收到消息后進(jìn)行解碼(將消息對(duì)象反序列化);
(5) 服務(wù)端存根(Server stub)根據(jù)解碼結(jié)果調(diào)用本地的服務(wù);
(6) 本地服務(wù)執(zhí)行并將結(jié)果返回給服務(wù)端存根(Server stub);
(7) 服務(wù)端存根(Server stub)將返回結(jié)果打包成消息(將結(jié)果消息對(duì)象序列化);
(8) 服務(wù)端(Server)通過(guò) Network Service 將消息發(fā)送到客戶端;
(9) 客戶端存根(Client stub)接收到結(jié)果消息,并進(jìn)行解碼(將結(jié)果消息發(fā)序列化);
(10) 客戶端(Client)得到最終結(jié)果。
RPC 就是要把 2、3、4、7、8、9 這些步驟都封裝起來(lái)。
什么情況下使用 RPC ?
RPC一般用于分布式系統(tǒng)中,且通常是內(nèi)部調(diào)用使用。例如,開(kāi)發(fā)電商系統(tǒng),需要拆分出用戶服務(wù)、商品服務(wù)、優(yōu)惠券服務(wù)、支付服務(wù)、訂單服務(wù)、物流服務(wù)、售后服務(wù)等等,這些服務(wù)之間都相互調(diào)用,這時(shí)內(nèi)部調(diào)用最好使用 RPC ,同時(shí)每個(gè)服務(wù)都可以獨(dú)立部署,獨(dú)立上線。 也就說(shuō),當(dāng)我們的項(xiàng)目太大,需要解耦服務(wù),擴(kuò)展性強(qiáng)、部署靈活,這時(shí)就要用到 RPC ,主要解決了分布式系統(tǒng)中,服務(wù)與服務(wù)之間的調(diào)用問(wèn)題。
目前流行的開(kāi)源 RPC 框架還是比較多的,有阿里巴巴的 Dubbo、Facebook 的 Thrift、google 的 gRPC、Twitter 的 Finagle 等。選擇什么樣的RPC框架,大家可以根據(jù)自己項(xiàng)目的需要來(lái)定。
已經(jīng)有HTTP請(qǐng)求,為什么還要RPC?
這主要是歷史原因!RPC在1984年就被人用來(lái)做分布式系統(tǒng)的通信,JAVA在1.1版本提供了Java版本的RPC框架(RMI),而HTTP協(xié)議直到1990年才開(kāi)始作為主流協(xié)議出現(xiàn),而且HTTP發(fā)明的場(chǎng)景是用于web架構(gòu),而不是分布式系統(tǒng)間通信,這導(dǎo)致了在很長(zhǎng)一段時(shí)間內(nèi),HTTP都是瀏覽器程序和后端web系統(tǒng)通信用的東西,沒(méi)有人會(huì)把HTTP作為分布式系統(tǒng)通信的協(xié)議。在很長(zhǎng)一段時(shí)間內(nèi),RPC才是正統(tǒng)。
隨著前端技術(shù)的發(fā)展,AJAX技術(shù)和JSON文檔在前端界逐漸成為主流,HTTP調(diào)用才擺脫html,開(kāi)始使用JSON這一相對(duì)簡(jiǎn)潔的文檔格式,為后面用于系統(tǒng)間調(diào)用定下基礎(chǔ)。最后,隨著RESTFUL思潮的興起,越來(lái)越多系統(tǒng)考慮用HTTP來(lái)提供服務(wù),但這時(shí)候,RPC已經(jīng)是各種大型分布式調(diào)用的標(biāo)配了。所以這個(gè)問(wèn)題我們也可以反過(guò)來(lái)問(wèn),既然有RPC了,為什么還要有HTTP請(qǐng)求?
既然有RPC了,為什么還要有HTTP請(qǐng)求?這個(gè)問(wèn)題不難回答,因?yàn)楝F(xiàn)在大部分的系統(tǒng)都是給瀏覽器使用的,因此,HTTP協(xié)議必不可少,而這大部分系統(tǒng)中的絕大部分,對(duì)于后端系統(tǒng)間調(diào)用的性能都是要求不高的,畢竟走的都是內(nèi)網(wǎng),它們關(guān)心的是前端和后端的性能,因此后端系統(tǒng)間調(diào)用如果能夠采用和前端一樣的技術(shù)棧,那無(wú)疑是維護(hù)成本最低的,而這時(shí)HTTP的技術(shù)生態(tài)也剛好滿足這個(gè)條件,所以就星星之火可以燎原了。那么對(duì)于少數(shù)的部分系統(tǒng),他們需要使用RPC,一可能是老架構(gòu),也不敢動(dòng)這塊,二是性能要求可能只有RPC可以滿足。
傳輸協(xié)議
- RPC,可以基于TCP協(xié)議,也可以基于HTTP協(xié)議
- HTTP,基于HTTP協(xié)議
傳輸效率
- RPC使用自定義的TCP協(xié)議,可以讓請(qǐng)求報(bào)文體積更小,或者使用HTTP2協(xié)議,也可以很好的減少報(bào)文的體積,提高傳輸效率
- HTTP,如果是基于HTTP1.1的協(xié)議,請(qǐng)求中會(huì)包含很多無(wú)用的內(nèi)容,如果是基于HTTP2.0,那么簡(jiǎn)單的封裝一下是可以作為一個(gè)RPC來(lái)使用的,這時(shí)標(biāo)準(zhǔn)RPC框架更多的是服務(wù)治理
性能消耗,主要在于序列化和反序列化的耗時(shí)
- RPC,可以基于thrift實(shí)現(xiàn)高效的二進(jìn)制傳輸
- HTTP,大部分是通過(guò)json來(lái)實(shí)現(xiàn)的,字節(jié)大小和序列化耗時(shí)都比thrift要更消耗性能
負(fù)載均衡
- RPC,基本都自帶了負(fù)載均衡策略
- HTTP,需要配置Nginx,HAProxy來(lái)實(shí)現(xiàn)
服務(wù)治理(下游服務(wù)新增,重啟,下線時(shí)如何不影響上游調(diào)用者)
- RPC,能做到自動(dòng)通知,不影響上游
- HTTP,需要事先通知,修改Nginx/HAProxy配置
總結(jié):
- RPC主要用于公司內(nèi)部的服務(wù)調(diào)用,性能消耗低,傳輸效率高,服務(wù)治理方便。
- HTTP主要用于對(duì)外的異構(gòu)環(huán)境,瀏覽器接口調(diào)用,App接口調(diào)用,第三方接口調(diào)用等。