什么是RPC?RPC框架dubbo的核心流程
一、REST 與 RPC:
1、什么是 REST 和 RPC 協(xié)議:
????????在單體應(yīng)用中,各模塊間的調(diào)用是通過編程語言級別的方法函數(shù)來實現(xiàn),但分布式系統(tǒng)運行在多臺機器上,一般來說,每個服務(wù)實例都是一個進程,服務(wù)間必須使用進程間通信機制來交互,而常見的通信協(xié)議主要有 RPC 和 REST 協(xié)議。
(1)REST:
????????REST 是基于 HTTP 實現(xiàn),使用 HTTP 協(xié)議處理數(shù)據(jù)通信,更加標準化與通用,因為無論哪種語言都支持 HTTP 協(xié)議。常見的 http API 都可以稱為 Rest 接口。REST 是一種架構(gòu)風格,指一組架構(gòu)約束條件和原則,滿足 REST 原則的應(yīng)用程序或設(shè)計就是 RESTful,RESTful 把一切內(nèi)容都視為資源。REST 強調(diào)組件交互的擴展性、接口的通用性、組件的獨立部署、以及減少交互延遲的中間件,它強化安全,也能封裝遺留系統(tǒng)。
(2)RPC:
????????RPC 是一種進程間通信方式,允許像調(diào)用本地服務(wù)一樣調(diào)用遠程服務(wù),通信協(xié)議大多采用二進制方式。
2、RPC 與 REST 的對比:
| 報文格式 | 二進制 | XML、JSON |
| 網(wǎng)絡(luò)協(xié)議 | TCP/HTTP/HTTP2 | HTTP/HTTP2 |
| 序列化開銷 | 低 | 一般 |
| 網(wǎng)絡(luò)開銷 | 低 | 一般 |
| 性能 | 高 | 一般 |
| 訪問便利性 | 客戶端比較方便,但二進制消息不可讀 | 文本消息開發(fā)者可讀,瀏覽器可訪問 |
| 代碼耦合度 | 耦合度高 | 松散耦合 |
| 通用性 | 低,對外開發(fā)需進一步轉(zhuǎn)換成REST協(xié)議 | 高,可直接對外開發(fā) |
| 使用場景 | 內(nèi)部服務(wù) | 外部服務(wù) |
(1)傳輸協(xié)議與性能:RPC 的傳輸協(xié)議靈活,可基于 TCP 實現(xiàn),由于 TCP 協(xié)議處于協(xié)議棧的下層,能夠更靈活地對協(xié)議字段進行定制,讓請求報文體積更小,減少網(wǎng)絡(luò)開銷,提高傳輸性能并縮短傳輸耗時,實現(xiàn)更大的吞吐量和并發(fā)數(shù)。REST 的 HTTP 協(xié)議是上層協(xié)議,發(fā)送包含同等內(nèi)容的信息,請求中會包含很多無用的內(nèi)容,所占用的字節(jié)數(shù)比使用 TCP 協(xié)議傳輸更高,因此在同等網(wǎng)絡(luò)下,HTTP 會比基于 TCP 協(xié)議的數(shù)據(jù)傳輸效率要低,傳輸耗時更長,不僅如此,REST 的 HTTP 大部分是通過 JSON 來實現(xiàn)的,序列化也更消耗性能,但如果是基于 HTTP2.0,那么經(jīng)過封裝也是可以作為一個 RPC 來使用的。
(2)靈活性、開放性與通用性:REST 通過 HTTP 實現(xiàn),相對更加規(guī)范與通用,無論哪種語言都支持 HTTP 協(xié)議,所以 REST 的調(diào)用和測試都很方便,但使用 RPC 則會有很多約束,而如果 RPC 需要對外開放的話,需要進一步處理,靈活性不如 REST
(3)使用場景:REST 主要用于對外開放的異構(gòu)環(huán)境,比如瀏覽器接口調(diào)用,Api 接口調(diào)用,第三方接口調(diào)用等。RPC 主要用于公司內(nèi)部的服務(wù)調(diào)用,性能消耗低,傳輸效率高,特別是大型的網(wǎng)站,內(nèi)部子系統(tǒng)較多、接口非常多的情況下適合使用 RPC
?
二、RPC 框架:
????????REST 和 RPC 都常用于微服務(wù)架構(gòu)中,微服務(wù)的好處之一,就是不限定服務(wù)的提供方使用什么技術(shù)選型,能夠?qū)崿F(xiàn)大公司跨團隊的技術(shù)解耦。 但是,如果沒有統(tǒng)一的通信框架,各個團隊的服務(wù)提供方就需要各自實現(xiàn)一套序列化、反序列化、網(wǎng)絡(luò)框架、連接池、收發(fā)線程、超時處理、狀態(tài)機等 “業(yè)務(wù)之外” 的重復(fù)技術(shù)勞動,造成整體的低效。所以,統(tǒng)一通信框架把上述 “業(yè)務(wù)之外” 的技術(shù)勞動統(tǒng)一處理,是服務(wù)化首要解決的問題。
1、什么是 RPC 框架:
????????RPC 框架的目標就是讓遠程服務(wù)調(diào)用更簡單、透明,由 RPC 框架負責屏蔽底層的序列化、傳輸方式和通信的細節(jié),開發(fā)者在使用時只需要了解誰在什么位置提供了什么樣的遠程服務(wù)接口即可,并不需要關(guān)心底層通信細節(jié)和調(diào)用過程。RPC 框架作為架構(gòu)微服務(wù)化的基礎(chǔ)組件,它能大大降低架構(gòu)微服務(wù)化的成本,提高調(diào)用方與服務(wù)提供方的研發(fā)效率。
2、RPC 框架的技術(shù)架構(gòu):
????????如下圖,在典型 RPC 的使用場景中,主要包含了服務(wù)發(fā)現(xiàn)、負載、容錯、網(wǎng)絡(luò)傳輸、序列化等組件,其中 ”RPC協(xié)議”就指明了服務(wù)如何進行序列化和網(wǎng)絡(luò)傳輸,這也是RPC的核心功能。
- 應(yīng)用級的RPC框架:Dubbo、Google gRPC
- 通信框架:Netty
- 遠程通信協(xié)議:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)
?3、RPC 框架的調(diào)用流程:
3.1、RPC 框架的核心組件:
(1)客戶端(Client):服務(wù)調(diào)用方。
(2)客戶端存根(Client Stub):存放服務(wù)端地址信息,將客戶端的請求參數(shù)數(shù)據(jù)信息打包成網(wǎng)絡(luò)消息,再通過網(wǎng)絡(luò)傳輸發(fā)送給服務(wù)端。
(3)服務(wù)端存根(Server Stub):接收客戶端發(fā)送過來的請求消息并進行解包,然后再調(diào)用本地服務(wù)進行處理。
(4)服務(wù)端(Server):服務(wù)的真正提供者。
3.2、RPC 的調(diào)用流程:
(1)服務(wù)消費者(Client 客戶端)通過本地調(diào)用的方式調(diào)用需要消費的服務(wù)
(2)客戶端存根(Client Stub)接收到調(diào)用請求后負責將方法、入?yún)⒌刃畔⑿蛄谢?#xff08;組裝)成能夠進行網(wǎng)絡(luò)傳輸?shù)南Ⅲw
(3)客戶端存根(Client Stub)找到遠程的服務(wù)地址,并且將消息通過網(wǎng)絡(luò)發(fā)送給服務(wù)端
(4)服務(wù)端存根(Server Stub)收到消息后進行解碼,反序列化操作
(5)服務(wù)端存根(Server Stub)根據(jù)解碼結(jié)果調(diào)用本地的服務(wù)進行相關(guān)處理
(6)服務(wù)端(Server)執(zhí)行具體的業(yè)務(wù)邏輯,并將處理結(jié)果返回給服務(wù)端存根(Server Stub)
(7)服務(wù)端存根(Server Stub)將返回結(jié)果序列化,并通過網(wǎng)絡(luò)發(fā)送給消費方
(8)客戶端存根(Client Stub)接收到消息,并進行解碼與反序列化
(9)服務(wù)消費方得到最終結(jié)果;
而RPC框架的實現(xiàn)目標則是將上面的第2-10步完好地封裝起來,也就是把調(diào)用、編碼/解碼的過程給封裝起來,讓用戶感覺上像調(diào)用本地服務(wù)一樣的調(diào)用遠程服務(wù)
4、如何實現(xiàn)一個RPC框架:
????????通過上面幾點的介紹,如果要我們實現(xiàn)一個 RPC 框架,我們應(yīng)該如果做呢?要實現(xiàn) 一個RPC 框架,我們只需要解決的以下幾件最基本的事情:
4.1、如何進行網(wǎng)絡(luò)通訊:
????????遠程調(diào)用中,客戶端和服務(wù)端的通訊是基于網(wǎng)絡(luò)連接的,所以首先需要建立通信連接,通過這個連接把請求信息的字節(jié)流傳給服務(wù)端,然后再把序列化后的響應(yīng)結(jié)果傳回客戶端,在這個通訊過程中,它所使用的協(xié)議是沒有限制的,能完成傳輸就行,但是在這里我們需要考慮兩個問題:如何選擇網(wǎng)絡(luò)協(xié)議 和 如何建立連接。
(1)網(wǎng)絡(luò)協(xié)議的選擇:多數(shù) RPC 框架選擇 TCP 作為傳輸協(xié)議,但其實 UDP 也可以,也有部分選擇HTTP,比如 gRPC 使用 HTTP2,但是不同的協(xié)議各有優(yōu)劣勢,TCP 更加高效,而 HTTP 在實際應(yīng)用中更加的靈活,具體需要根據(jù)使用場景來選擇,下文會介紹如何選擇正確的網(wǎng)絡(luò)傳輸協(xié)議
(2)通訊連接的建立:RPC 所有交換的數(shù)據(jù)都在這個連接里傳輸,這個連接可以是按需連接(需要調(diào)用時就先建立連接,調(diào)用結(jié)束后就立馬斷掉),也可以是長連接(客戶端和服務(wù)器建立起連接之后保持長期持有,不管此時有無數(shù)據(jù)包的發(fā)送,可以配合心跳檢測機制定期檢測建立的連接是否存活有效),多個遠程過程調(diào)用共享同一個連接。
4.2、如何那行服務(wù)尋址:
????????解決尋址的問題,也就是說服務(wù)端如何確定客戶端要調(diào)用的函數(shù),在本地調(diào)用中,函數(shù)是直接通過函數(shù)指針來指定的,但是在遠程調(diào)用中,函數(shù)指針是不行的,因為兩個進程的地址空間是完全不一樣的。所以在遠程調(diào)用中,客戶端和服務(wù)端需要分別維護一個【ID -> 函數(shù)】的映射表,ID在所有進程中都是唯一確定的,客戶端在做遠程過程調(diào)用時,附上這個ID,服務(wù)端通過查表,來確定客戶端需要調(diào)用的函數(shù),然后執(zhí)行相應(yīng)函數(shù)的代碼。
????????而尋址問題的具體實現(xiàn)方式,則可以通過注冊中心,服務(wù)提供者完成后,對外暴露相應(yīng)的功能并將自己注冊到注冊中心上,接著服務(wù)消費者從注冊中心尋找服務(wù),然后調(diào)用該服務(wù)對應(yīng)的方法完成遠程調(diào)用
(1)從服務(wù)提供者的角度看:
- 當服務(wù)提供者啟動的時候,需要將自己提供的服務(wù)注冊到指定的注冊中心,以便服務(wù)消費者能夠通過服務(wù)注冊中心進行查找;
- 當服務(wù)提供者由于各種原因致使提供的服務(wù)停止時,需要向注冊中心注銷停止的服務(wù);服務(wù)的提供者需要定期向服務(wù)注冊中心發(fā)送心跳檢測,服務(wù)注冊中心如果一段時間未收到來自服務(wù)提供者的心跳后,認為該服務(wù)提供者已經(jīng)停止服務(wù),則將該服務(wù)從注冊中心上去掉。
(2)從調(diào)用者的角度看:
- 服務(wù)的調(diào)用者啟動的時候根據(jù)自己訂閱的服務(wù)向服務(wù)注冊中心查找服務(wù)提供者的地址等信息;
- 當服務(wù)調(diào)用者消費的服務(wù)上線或者下線的時候,注冊中心會告知該服務(wù)的調(diào)用者;
- 服務(wù)調(diào)用者下線的時候,則取消訂閱。
4.3、如何序列化和反序列化:
????????在本地調(diào)用中,我們只需要把參數(shù)信息壓到內(nèi)存棧中,然后讓函數(shù)自己去棧中讀取,但是遠程過程調(diào)用時,客戶端跟服務(wù)端是不同的進程,不能通過內(nèi)存來傳遞參數(shù)。所以遠程過程調(diào)用中,客戶端和服務(wù)端交互時,方法的參數(shù)和結(jié)果需要通過底層的網(wǎng)絡(luò)協(xié)議如TCP傳遞,由于網(wǎng)絡(luò)協(xié)議是基于二進制的(只有二進制數(shù)據(jù)才能在網(wǎng)絡(luò)中傳輸),那么這些值需要序列化成二進制的形式,通過尋址和傳輸將序列化的二進制發(fā)送目標服務(wù)器。目標服務(wù)器接收到數(shù)據(jù)時,需要對數(shù)據(jù)進行反序列化。序列化和反序列化的速度也會影響遠程調(diào)用的效率。
- 將對象轉(zhuǎn)換成二進制流的過程叫做序列化
- 將二進制流轉(zhuǎn)換成對象的過程叫做反序列化
5、如何選擇正確的PRC網(wǎng)絡(luò)傳輸協(xié)議?
????????在 RPC 中可選的網(wǎng)絡(luò)傳輸方式有多種,比如 TCP 協(xié)議、UDP 協(xié)議、HTTP 協(xié)議。每一種協(xié)議對整體的性能和效率都有不同的影響,那如何選擇一個正確的網(wǎng)絡(luò)傳輸協(xié)議呢?針對這個問題,我們首先要搞明白各種傳輸協(xié)議在 RPC 中的工作方式:
- 基于 TCP 的協(xié)議實現(xiàn)的 RPC 調(diào)用,由于 TCP 協(xié)議處于協(xié)議棧的下層,能夠更加靈活地對協(xié)議字段進行定制,讓請求報文體積更小,減少網(wǎng)絡(luò)開銷,提高傳輸性能并縮短傳輸耗時,實現(xiàn)更大的吞吐量和并發(fā)數(shù)。但是需要更多關(guān)注底層復(fù)雜的細節(jié),實現(xiàn)的代價更高,同時對不同平臺,如安卓,iOS 等,需要重新開發(fā)出不同的工具包來進行請求發(fā)送和相應(yīng)解析,工作量大,難以快速響應(yīng)和滿足用戶需求。
- 基于 HTTP 協(xié)議實現(xiàn)的 RPC 則可以使用 JSON 和 XML 格式的請求或響應(yīng)數(shù)據(jù),而 JSON 和 XML 作為通用的格式標準(使用 HTTP 協(xié)議也需要序列化和反序列化,不過這不是該協(xié)議下關(guān)心的內(nèi)容,成熟的 Web 程序已經(jīng)做好了序列化內(nèi)容),開源的解析工具已經(jīng)相當成熟,在其上進行二次開發(fā)會非常便捷和簡單。但是由于 HTTP 協(xié)議是上層協(xié)議,發(fā)送包含同等內(nèi)容的信息,請求中會包含很多無用的內(nèi)容,所占用的字節(jié)數(shù)比使用 TCP 協(xié)議傳輸更高,因此在同等網(wǎng)絡(luò)下,HTTP 會比基于 TCP 協(xié)議的數(shù)據(jù)傳輸效率要低,傳輸耗時更長,當然壓縮數(shù)據(jù),能夠縮小這一差距。
三、RPC框架dubbo:
1、dubbo 是什么?
????????前面講到,RPC 常用于微服務(wù)架構(gòu)中,而 RPC 框架作為架構(gòu)微服務(wù)化的基礎(chǔ)組件,能大大降低架構(gòu)微服務(wù)化的成本,提高調(diào)用方與服務(wù)提供方的研發(fā)效率。而 Dubbo 是阿里巴巴開源的基于 Java 的 RPC 分布式服務(wù)框架,提供高性能和透明化的 RPC 遠程服務(wù)調(diào)用方案,以及 SOA 服務(wù)治理方案。另外,基于 Spring Cloud Alibaba 技術(shù)棧的 Spring-cloud-alibaba-dubbo 更是對 dubbo 技術(shù)進行了封裝,在基于 Spring Cloud Alibaba 提供的 Nacos 注冊中心下,提供了 Dubbo 和 Spring Cloud 的整合方案,即 Dubbo Spring Cloud,使得服務(wù)內(nèi)部的 RPC 協(xié)議調(diào)用幾乎是零成本的改造,實現(xiàn)了基于 RPC 的服務(wù)調(diào)用。
2、dubbo 的執(zhí)行流程:
2.1、dubbo 總體流程:
- 紫色虛線:啟動時完成的功能
- 藍色虛線:運行過程中執(zhí)行的功能,異步調(diào)用
- 藍色實線:運行過程中執(zhí)行的功能,同步調(diào)用
2.1.1、dubbo 的總體執(zhí)行流程說明如下:
(1)啟動容器,加載,運行服務(wù)提供者。
(2)服務(wù)提供者在啟動時,向注冊中心注冊自己提供的服務(wù)。
(3)服務(wù)消費者在啟動時,向注冊中心訂閱自己所需的服務(wù)。
(4)注冊中心返回服務(wù)提供者地址列表給消費者,消費者接收到之后,緩存在本地中,如果內(nèi)容有變更,注冊中心將基于長連接推送變更數(shù)據(jù)給消費者。
(5)服務(wù)消費者,從提供者地址列表中,基于軟負載均衡算法,選擇一臺提供者進行調(diào)用,如果調(diào)用失敗,再選另一臺調(diào)用。
(6)服務(wù)消費者和提供者,在內(nèi)存中累計調(diào)用次數(shù)和調(diào)用時間,定時每分鐘發(fā)送一次統(tǒng)計數(shù)據(jù)到監(jiān)控中心。
在consumer中使用了代理模式,創(chuàng)建了一個Provider類的一個代理對象。通過代理對象獲取Provider中的真實功能,起到保護Provider真實功能的作用。
2.1.2、dubbo 的整個執(zhí)行流程可以理解為生產(chǎn)者-消費者模型+注冊中心+監(jiān)控中心,這樣設(shè)計的原因在于:
- Consumer 與 Provider 解偶,雙方都可以橫向增減節(jié)點數(shù)
- 注冊中心對本身可做對等集群,可動態(tài)增減節(jié)點,并且任意一臺宕掉后,將自動切換到另一臺
- 去中心化,雙方不直接依懶注冊中心,即使注冊中心全部宕機短時間內(nèi)也不會影響服務(wù)的調(diào)用
- 服務(wù)提供者無狀態(tài),任意一臺宕掉后,不影響使用
2.2、dubbo 同步調(diào)用原理:
2.2.1、dubbo 同步調(diào)用流程:
- (1)客戶端線程調(diào)用遠程接口,向服務(wù)端發(fā)送請求,同時當前線程應(yīng)該處于“暫停“狀態(tài),即線程不能向后執(zhí)行了,必需要拿到服務(wù)端給自己的結(jié)果后才能向后執(zhí)行
- (2)服務(wù)端接到客戶端請求后,處理請求,將結(jié)果給客戶端
- (3)客戶端收到結(jié)果,然后當前線程繼續(xù)往后執(zhí)行
????????dubbo 中使用了 Socket 來建立長連接、數(shù)據(jù)傳輸,而底層結(jié)合了的 Apache mina 框架,Apache mina 框架基于Reactor模型通信框架,基于tcp長連接。dubbo 使用 IoSession.write() 方法進行遠程調(diào)用與發(fā)送消息,這個方法的遠程調(diào)用過程異步的,即對于當前線程來說,將請求發(fā)送出來,線程就可以往后執(zhí)行了,至于服務(wù)端的結(jié)果,是服務(wù)端處理完成后,再以消息的形式發(fā)送給客戶端的。于是這里出現(xiàn)了2個問題:
(1)當前線程怎么讓它“暫停”,等結(jié)果回來后,再向后執(zhí)行:
????????先生成一個對象 obj,在一個全局 map 里 put(ID,obj) 存放起來,再用 synchronized 獲取 obj 鎖,再調(diào)用 obj.wait() 讓當前線程處于等待狀態(tài),然后另一消息監(jiān)聽線程等到服務(wù)端處理結(jié)果到來,再 map.get(ID) 找到 obj,再用 synchronized 獲取obj鎖,再調(diào)用 obj.notifyAll() 喚醒前面處于等待狀態(tài)的線程。
(2)Socket通信是一個全雙工的方式,當有多個線程同時進行遠程方法調(diào)用,這時 client 與 server 間的 socket 連接上會有很多雙方發(fā)送的消息傳遞,前后順序也可能是亂七八糟的,server處理完結(jié)果后,將結(jié)果消息發(fā)送給client,client收到很多消息,怎么知道哪個消息結(jié)果是原先哪個線程調(diào)用的:
????????使用一個ID,讓其唯一,然后傳遞給服務(wù)端,再服務(wù)端又回傳回來,這樣就知道結(jié)果是原先哪個線程的了
2.2.2、dubbo同步調(diào)用原理:
(1)客戶端使用一個線程調(diào)用遠程接口,生成一個唯一 ID,Dubbo 是使用 AtomicLong 從 0 開始累計數(shù)字的
(2)將打包的方法調(diào)用信息(如調(diào)用的接口名稱,方法名稱,參數(shù)值列表等),和處理結(jié)果的回調(diào)對象callback,全部封裝在一起,組成一個對象object
(3)向?qū)iT存放調(diào)用信息的全局 ConcurrentHashMap 里面 put(ID, object)
(4)將 ID 和打包的方法調(diào)用信息封裝成一對象 connRequest,使用 IoSession.write(connRequest) 異步發(fā)送出去
(5)當前線程再使用 callback 的 get() 方法試圖獲取遠程返回的結(jié)果,在get()內(nèi)部,則先使用synchronized獲取回調(diào)對象callback的鎖, 檢測是否已經(jīng)獲取到結(jié)果,如果沒有,然后調(diào)用 callback 的 wait() 方法,釋放 callback 上的鎖,讓當前線程處于等待狀態(tài)。
(6)服務(wù)端接收到請求并處理后,將結(jié)果(包含了唯一ID)回傳給客戶端,客戶端 socket 連接上專門監(jiān)聽消息的線程收到消息后,分析結(jié)果,取到ID,再從前面的 ConcurrentHashMap 里面 get(ID),從而找到 callback,將方法調(diào)用結(jié)果設(shè)置到callback對象里。
(7)最后監(jiān)聽線程再獲取回調(diào)對象 callback 的 synchronized 鎖(因為前面調(diào)用過wait() 導(dǎo)致釋放callback的鎖),先使用 notifyAll() 喚醒前面處于等待狀態(tài)的線程繼續(xù)執(zhí)行,這樣 callback 的 get( )方法繼續(xù)執(zhí)行就能拿到調(diào)用結(jié)果了,至此,整個過程結(jié)束
需要注意的是,這里的callback對象是每次調(diào)用產(chǎn)生一個新的,不能共享;另外ID必需至少保證在一個Socket連接里面是唯一的。
3、dubbo 的負載均衡策略:
dubbo 的負載均衡策略:https://www.cnblogs.com/wyq178/p/9822731.html
(1)隨機調(diào)用策略(默認):隨機選擇服務(wù)器節(jié)點,該策略可以對不同服務(wù)器實例設(shè)置不同的權(quán)重,權(quán)重越大分配流量越高
(2)輪詢調(diào)用策略:均勻地將請求分配到各個機器上。如果各個機器的性能不一樣,容易導(dǎo)致性能差的機器負載過高,所以此時需要調(diào)整權(quán)重,讓性能差的機器承載權(quán)重小一些,流量少一些。
(3)最少活躍數(shù)策略:根據(jù)服務(wù)器的運行狀態(tài)去選擇服務(wù),如果某個機器性能越差,那么接收的請求越少,越不活躍,此時就會給不活躍的性能差的機器分配更少的請求
(4)一致性哈希算法:相同參數(shù)的請求一定會被分發(fā)到固定的服務(wù)器節(jié)點。當某個服務(wù)器節(jié)點掛掉的時候,會基于虛擬節(jié)點均勻分配剩余的流量,抖動不會太大。
4、dubbo 的容錯機制:
Failover(默認):失敗自動切換,當出現(xiàn)失敗,重試其它服務(wù)器,默認為2次。通常用于讀操作,但重試會帶來更長延遲。
Failfast:快速失敗,只發(fā)起一次調(diào)用,失敗立即報錯。通常用于非冪等性的寫操作,比如新增記錄。
Failsafe:失敗安全,出現(xiàn)異常時,直接忽略。通常用于寫入審計日志等操作。
Failback:失敗自動恢復(fù),后臺記錄失敗請求,定時重發(fā)。通常用于消息通知操作。
Forking:并行調(diào)用多個服務(wù)器,只要一個成功即返回。通常用于實時性要求較高的讀操作,但需要浪費更多服務(wù)資源。可通過 forks=”2″ 來設(shè)置最大并行數(shù)。
Broadcast:廣播調(diào)用所有提供者,逐個調(diào)用,任意一臺報錯則報錯 。通常用于通知所有提供者更新緩存或日志等本地資源信息。
5、dubbo支持哪些協(xié)議和適用場景:
(1)dubbo:單一長連接和 NIO 異步通訊,適合大并發(fā)小數(shù)據(jù)量的服務(wù)調(diào)用,以及消費者遠大于提供者的情況。傳輸協(xié)議 TCP,異步 Hessian 序列化。Dubbo 官方推薦使用 dubbo 協(xié)議。但是,dubbo 協(xié)議不適合傳送大數(shù)據(jù)量的服務(wù),比如傳文件,傳視頻等,除非請求量很低
(2)RMI: 采用 JDK 標準的 RMI 協(xié)議實現(xiàn),使用 Java 標準序列化機制,傳輸參數(shù)和返回參數(shù)對象需要實現(xiàn) Serializable 接口,使用阻塞式短連接,傳輸數(shù)據(jù)包大小混合,消費者和提供者個數(shù)差不多,可傳文件,傳輸協(xié)議 TCP。多個短連接,基于 TCP 協(xié)議傳輸,同步傳輸,適用常規(guī)的遠程服務(wù)調(diào)用和 RMI 互操作。在依賴低版本的 Common-Collections 包,Java 序列化存在安全漏洞。
(3)WebService:基于 WebService 的遠程調(diào)用協(xié)議,集成 CXF 實現(xiàn),提供和原生 WebService 的互操作。多個短連接,基于 HTTP 傳輸,同步傳輸,適用系統(tǒng)集成和跨語言調(diào)用。
(4)HTTP: 基于 Http 表單提交的遠程調(diào)用協(xié)議,使用 Spring 的 HttpInvoke 實現(xiàn)。多個短連接,傳輸協(xié)議 HTTP,傳入?yún)?shù)大小混合,提供者個數(shù)多于消費者,需要給應(yīng)用程序和瀏覽器 JS 調(diào)用。
(5)Hessian:集成 Hessian 服務(wù),基于 HTTP 通訊,采用 Servlet 暴露服務(wù),Dubbo 內(nèi)嵌 Jetty 作為服務(wù)器時默認實現(xiàn),提供與 Hession 服務(wù)互操作。多個短連接,同步 HTTP 傳輸,Hessian 序列化,傳入?yún)?shù)較大,提供者大于消費者,提供者壓力較大,可傳文件。
(6)Redis:基于 Redis 實現(xiàn)的RPC協(xié)議。
(7)Memcache:基于 Memcache實現(xiàn)的 RPC 協(xié)議。
6、dubbo 的通信框架:
dubbo 默認使用 Netty 作為通訊框架
7、dubbo的架構(gòu)設(shè)計:
?7.1、圖例說明:
- 左邊淡藍背景的為服務(wù)消費方使用的接口,右邊淡綠色背景的為服務(wù)提供方使用的接口,位于中軸線上的為雙方都用到的接口。
- 圖中從下至上分為 10 層,各層均為單向依賴,右邊的黑色箭頭代表層之間的依賴關(guān)系,每一層都可以剝離上層被復(fù)用,其中,Service 和 Config 層為 API,其它各層均為 SPI。
- 圖中綠色小塊的為擴展接口,藍色小塊為實現(xiàn)類,圖中只顯示用于關(guān)聯(lián)各層的實現(xiàn)類。
- 圖中藍色虛線為初始化過程,即啟動時組裝鏈,紅色實線為方法調(diào)用過程,即運行時調(diào)時鏈,紫色三角箭頭為繼承,可以把子類看作父類的同一個節(jié)點,線上的文字為調(diào)用的方法。
7.2、各層說明:
(1)接口服務(wù)層(Service):該層與實際業(yè)務(wù)邏輯相關(guān),根據(jù) provider 和 consumer 的業(yè)務(wù)設(shè)計對應(yīng)的接口和實現(xiàn)
(2)配置層(Config):對外配置接口,以 ServiceConfig 和 ReferenceConfig 為中心
(3)服務(wù)代理層(Proxy):服務(wù)接口透明代理,生成服務(wù)的客戶端 Stub 和 服務(wù)端的 Skeleton,以 ServiceProxy 為中心,擴展接口為 ProxyFactory
(4)服務(wù)注冊層(Registry):封裝服務(wù)地址的注冊和發(fā)現(xiàn),以服務(wù) URL 為中心,擴展接口為 RegistryFactory、Registry、RegistryService
(5)路由層(Cluster):封裝多個提供者的路由和負載均衡,并橋接注冊中心,以Invoker 為中心,擴展接口為 Cluster、Directory、Router 和 LoadBlancce
(6)監(jiān)控層(Monitor):RPC 調(diào)用次數(shù)和調(diào)用時間監(jiān)控,以 Statistics 為中心,擴展接口為 MonitorFactory、Monitor 和 MonitorService
(7)遠程調(diào)用層(Protocal):封裝 RPC 調(diào)用,以 Invocation 和 Result 為中心,擴展接口為 Protocal、Invoker 和 Exporter
(8)信息交換層(Exchange):封裝請求響應(yīng)模式,同步轉(zhuǎn)異步。以 Request 和Response 為中心,擴展接口為 Exchanger、ExchangeChannel、ExchangeClient 和 ExchangeServer
(9)網(wǎng)絡(luò) 傳輸 層(Transport):抽象 mina 和 netty 為統(tǒng)一接口,以 Message 為中心,擴展接口為 Channel、Transporter、Client、Server 和 Codec
(10)數(shù)據(jù)序列化層(Serialize):可復(fù)用的一些工具,擴展接口為 Serialization、ObjectInput、ObjectOutput 和 ThreadPool
dubbo 的架構(gòu)設(shè)計詳情推薦閱讀官方文檔:https://dubbo.apache.org/zh/docs/v2.7/dev/design/
參考文章:https://juejin.cn/post/6844904127076499463
總結(jié)
以上是生活随笔為你收集整理的什么是RPC?RPC框架dubbo的核心流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java IO篇:什么是 Proacto
- 下一篇: RocketMQ-docker镜像的制作