看了這篇Dubbo RPC面試題,讓天下沒(méi)有難面的面試題!

前言:

RPC非常重要,很多人面試的時(shí)候都掛在了這個(gè)地方!你要是還不懂RPC是什么?他的基本原理是什么?你一定要把下邊的內(nèi)容記起來(lái)!好好研究一下!特別是文中給出的一張關(guān)于RPC的基本流程圖,重點(diǎn)中的重點(diǎn),Dubbo RPC的基本執(zhí)行流程就是他,RPC框架的基本原理也是他,別說(shuō)我沒(méi)告訴你!看了下邊的內(nèi)容你要掌握的內(nèi)容如下,當(dāng)然還有很多:

RPC的由來(lái),是怎樣一步步演進(jìn)出來(lái)的;

RPC的基本架構(gòu)是什么;

RPC的基本實(shí)現(xiàn)原理,就是下邊的這張圖,重點(diǎn)中的重點(diǎn);

REST?和?SOAP、RPC?有何區(qū)別呢?

整個(gè)調(diào)用的過(guò)程經(jīng)歷了哪幾步和Spring?MVC的執(zhí)行流程一樣,相當(dāng)重要;

一、為什么要有RPC

隨著互聯(lián)網(wǎng)的發(fā)展,網(wǎng)站應(yīng)用的規(guī)模不斷擴(kuò)大,常規(guī)的垂直應(yīng)用架構(gòu)已無(wú)法應(yīng)對(duì),分布式服務(wù)架構(gòu)以及流動(dòng)計(jì)算架構(gòu)勢(shì)在必行,亟需一個(gè)治理系統(tǒng)確保架構(gòu)有條不紊的演進(jìn)。

1、單一應(yīng)用架構(gòu)

當(dāng)網(wǎng)站流量很小時(shí),只需一個(gè)應(yīng)用,將所有功能都部署在一起,以減少部署節(jié)點(diǎn)和成本。此時(shí),用于簡(jiǎn)化增刪改查工作量的數(shù)據(jù)訪問(wèn)框架(ORM)?是關(guān)鍵。

2、垂直應(yīng)用架構(gòu)

當(dāng)訪問(wèn)量逐漸增大,單一應(yīng)用增加機(jī)器帶來(lái)的加速度越來(lái)越小,將應(yīng)用拆成互不相干的幾個(gè)應(yīng)用,以提升效率。此時(shí),用于加速前端頁(yè)面開(kāi)發(fā)的?Web框架(MVC)?是關(guān)鍵。

3、分布式服務(wù)架構(gòu)

當(dāng)垂直應(yīng)用越來(lái)越多,應(yīng)用之間交互不可避免,將核心業(yè)務(wù)抽取出來(lái),作為獨(dú)立的服務(wù),逐漸形成穩(wěn)定的服務(wù)中心,使前端應(yīng)用能更快速的響應(yīng)多變的市場(chǎng)需求。

此時(shí),用于提高業(yè)務(wù)復(fù)用及整合的分布式服務(wù)框架(RPC),提供統(tǒng)一的服務(wù)是關(guān)鍵。

例如:各個(gè)團(tuán)隊(duì)的服務(wù)提供方就不要各自實(shí)現(xiàn)一套序列化、反序列化、網(wǎng)絡(luò)框架、連接池、收發(fā)線程、超時(shí)處理、狀態(tài)機(jī)等“業(yè)務(wù)之外”的重復(fù)技術(shù)勞動(dòng),造成整體的低效。

PS:其實(shí)上述三個(gè)原因也是為什么要有Dubbo的原因!不信你去Dubbo官網(wǎng)去看!

4、流動(dòng)計(jì)算架構(gòu)

PS:這個(gè)屬于擴(kuò)展內(nèi)容,摘自Dubbo官網(wǎng),屬于架構(gòu)演進(jìn)的一個(gè)過(guò)程

當(dāng)服務(wù)越來(lái)越多,容量的評(píng)估,小服務(wù)資源的浪費(fèi)等問(wèn)題逐漸顯現(xiàn),此時(shí)需增加一個(gè)調(diào)度中心基于訪問(wèn)壓力實(shí)時(shí)管理集群容量,提高集群利用率。此時(shí),用于提高機(jī)器利用率的資源調(diào)度和治理中心(SOA)是關(guān)鍵。

5、另外一個(gè)原因

就是因?yàn)樵趲讉€(gè)進(jìn)程內(nèi)(應(yīng)用分布在不同的機(jī)器上),無(wú)法共用內(nèi)存空間,或者在一臺(tái)機(jī)器內(nèi)通過(guò)本地調(diào)用無(wú)法完成相關(guān)的需求,比如不同的系統(tǒng)之間的通訊,甚至不同組織之間的通訊。此外由于機(jī)器的橫向擴(kuò)展,需要在多臺(tái)機(jī)器組成的集群上部署應(yīng)用等等。

所以,統(tǒng)一RPC框架來(lái)解決提供統(tǒng)一的服務(wù)。

二、什么是RPC

RPC(Remote Procedure Call Protocol)遠(yuǎn)程過(guò)程調(diào)用協(xié)議,它是一種通過(guò)網(wǎng)絡(luò)從遠(yuǎn)程計(jì)算機(jī)程序上請(qǐng)求服務(wù),而不需要了解底層網(wǎng)絡(luò)技術(shù)的協(xié)議。簡(jiǎn)言之,RPC使得程序能夠像訪問(wèn)本地系統(tǒng)資源一樣,去訪問(wèn)遠(yuǎn)端系統(tǒng)資源。比較關(guān)鍵的一些方面包括:通訊協(xié)議、序列化、資源(接口)描述、服務(wù)框架、性能、語(yǔ)言支持等。

簡(jiǎn)單的說(shuō),RPC就是從一臺(tái)機(jī)器(客戶端)上通過(guò)參數(shù)傳遞的方式調(diào)用另一臺(tái)機(jī)器(服務(wù)器)上的一個(gè)函數(shù)或方法(可以統(tǒng)稱為服務(wù))并得到返回的結(jié)果。

三、PRC架構(gòu)組件

一個(gè)基本的RPC架構(gòu)里面應(yīng)該至少包含以下4個(gè)組件:

客戶端(Client):服務(wù)調(diào)用方(服務(wù)消費(fèi)者)

客戶端存根(Client?Stub):存放服務(wù)端地址信息,將客戶端的請(qǐng)求參數(shù)數(shù)據(jù)信息打包成網(wǎng)絡(luò)消息,再通過(guò)網(wǎng)絡(luò)傳輸發(fā)送給服務(wù)端

服務(wù)端存根(Server?Stub):接收客戶端發(fā)送過(guò)來(lái)的請(qǐng)求消息并進(jìn)行解包,然后再調(diào)用本地服務(wù)進(jìn)行處理

服務(wù)端(Server):服務(wù)的真正提供者

具體調(diào)用過(guò)程:

服務(wù)消費(fèi)者(client客戶端)通過(guò)調(diào)用本地服務(wù)的方式調(diào)用需要消費(fèi)的服務(wù);

客戶端存根(client?stub)接收到調(diào)用請(qǐng)求后負(fù)責(zé)將方法、入?yún)⒌刃畔⑿蛄谢ńM裝)成能夠進(jìn)行網(wǎng)絡(luò)傳輸?shù)南Ⅲw;

客戶端存根(client?stub)找到遠(yuǎn)程的服務(wù)地址,并且將消息通過(guò)網(wǎng)絡(luò)發(fā)送給服務(wù)端;

服務(wù)端存根(server?stub)收到消息后進(jìn)行解碼(反序列化操作);

服務(wù)端存根(server?stub)根據(jù)解碼結(jié)果調(diào)用本地的服務(wù)進(jìn)行相關(guān)處理;

本地服務(wù)執(zhí)行具體業(yè)務(wù)邏輯并將處理結(jié)果返回給服務(wù)端存根(server?stub);

服務(wù)端存根(server?stub)將返回結(jié)果重新打包成消息(序列化)并通過(guò)網(wǎng)絡(luò)發(fā)送至消費(fèi)方;

客戶端存根(client?stub)接收到消息,并進(jìn)行解碼(反序列化);

服務(wù)消費(fèi)方得到最終結(jié)果;

而RPC框架的實(shí)現(xiàn)目標(biāo)則是將上面的第2-10步完好地封裝起來(lái),也就是把調(diào)用、編碼/解碼的過(guò)程給封裝起來(lái),讓用戶感覺(jué)上像調(diào)用本地服務(wù)一樣的調(diào)用遠(yuǎn)程服務(wù)。

四、RPC和SOA、SOAP、REST的區(qū)別

1、REST

可以看著是HTTP協(xié)議的一種直接應(yīng)用,默認(rèn)基于JSON作為傳輸格式,使用簡(jiǎn)單,學(xué)習(xí)成本低效率高,但是安全性較低。

2、SOAP

SOAP是一種數(shù)據(jù)交換協(xié)議規(guī)范,是一種輕量的、簡(jiǎn)單的、基于XML的協(xié)議的規(guī)范。而SOAP可以看著是一個(gè)重量級(jí)的協(xié)議,基于XML、SOAP在安全方面是通過(guò)使用XML-Security和XML-Signature兩個(gè)規(guī)范組成了WS-Security來(lái)實(shí)現(xiàn)安全控制的,當(dāng)前已經(jīng)得到了各個(gè)廠商的支持?。

它有什么優(yōu)點(diǎn)?簡(jiǎn)單總結(jié)為:易用、靈活、跨語(yǔ)言、跨平臺(tái)。

3、SOA

面向服務(wù)架構(gòu),它可以根據(jù)需求通過(guò)網(wǎng)絡(luò)對(duì)松散耦合的粗粒度應(yīng)用組件進(jìn)行分布式部署、組合和使用。服務(wù)層是SOA的基礎(chǔ),可以直接被應(yīng)用調(diào)用,從而有效控制系統(tǒng)中與軟件代理交互的人為依賴性。

SOA是一種粗粒度、松耦合服務(wù)架構(gòu),服務(wù)之間通過(guò)簡(jiǎn)單、精確定義接口進(jìn)行通訊,不涉及底層編程接口和通訊模型。SOA可以看作是B/S模型、XML(標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言的子集)/Web?Service技術(shù)之后的自然延伸。

4、REST?和?SOAP、RPC?有何區(qū)別呢?

沒(méi)什么太大區(qū)別,他們的本質(zhì)都是提供可支持分布式的基礎(chǔ)服務(wù),最大的區(qū)別在于他們各自的的特點(diǎn)所帶來(lái)的不同應(yīng)用場(chǎng)景?。

五、RPC框架需要解決的問(wèn)題?

如何確定客戶端和服務(wù)端之間的通信協(xié)議?

如何更高效地進(jìn)行網(wǎng)絡(luò)通信?

服務(wù)端提供的服務(wù)如何暴露給客戶端?

客戶端如何發(fā)現(xiàn)這些暴露的服務(wù)?

如何更高效地對(duì)請(qǐng)求對(duì)象和響應(yīng)結(jié)果進(jìn)行序列化和反序列化操作?

六、RPC的實(shí)現(xiàn)基礎(chǔ)?

需要有非常高效的網(wǎng)絡(luò)通信,比如一般選擇Netty作為網(wǎng)絡(luò)通信框架;

需要有比較高效的序列化框架,比如谷歌的Protobuf序列化框架;

可靠的尋址方式(主要是提供服務(wù)的發(fā)現(xiàn)),比如可以使用Zookeeper來(lái)注冊(cè)服務(wù)等等;

如果是帶會(huì)話(狀態(tài))的RPC調(diào)用,還需要有會(huì)話和狀態(tài)保持的功能;

七、RPC使用了哪些關(guān)鍵技術(shù)?

1、動(dòng)態(tài)代理

生成Client Stub(客戶端存根)和Server Stub(服務(wù)端存根)的時(shí)候需要用到Java動(dòng)態(tài)代理技術(shù),可以使用JDK提供的原生的動(dòng)態(tài)代理機(jī)制,也可以使用開(kāi)源的:CGLib代理,Javassist字節(jié)碼生成技術(shù)。

2、序列化和反序列化

在網(wǎng)絡(luò)中,所有的數(shù)據(jù)都將會(huì)被轉(zhuǎn)化為字節(jié)進(jìn)行傳送,所以為了能夠使參數(shù)對(duì)象在網(wǎng)絡(luò)中進(jìn)行傳輸,需要對(duì)這些參數(shù)進(jìn)行序列化和反序列化操作。

序列化:把對(duì)象轉(zhuǎn)換為字節(jié)序列的過(guò)程稱為對(duì)象的序列化,也就是編碼的過(guò)程。

反序列化:把字節(jié)序列恢復(fù)為對(duì)象的過(guò)程稱為對(duì)象的反序列化,也就是解碼的過(guò)程。

目前比較高效的開(kāi)源序列化框架:如Kryo、FastJson和Protobuf等。

3、NIO通信

出于并發(fā)性能的考慮,傳統(tǒng)的阻塞式?IO?顯然不太合適,因此我們需要異步的?IO,即?NIO。Java?提供了?NIO?的解決方案,Java?7?也提供了更優(yōu)秀的?NIO.2?支持??梢赃x擇Netty或者M(jìn)INA來(lái)解決NIO數(shù)據(jù)傳輸?shù)膯?wèn)題。

4、服務(wù)注冊(cè)中心

可選:Redis、Zookeeper、Consul?、Etcd。一般使用ZooKeeper提供服務(wù)注冊(cè)與發(fā)現(xiàn)功能,解決單點(diǎn)故障以及分布式部署的問(wèn)題(注冊(cè)中心)。

八、主流RPC框架有哪些

RMI

Hessian

protobuf-rpc-pro

Thrift

Avro

Dubbo

九、RPC的實(shí)現(xiàn)原理架構(gòu)圖

PS:這張圖非常重點(diǎn),是PRC的基本原理,請(qǐng)大家一定記??!

也就是說(shuō)兩臺(tái)服務(wù)器A,B,一個(gè)應(yīng)用部署在A服務(wù)器上,想要調(diào)用B服務(wù)器上應(yīng)用提供的函數(shù)/方法,由于不在一個(gè)內(nèi)存空間,不能直接調(diào)用,需要通過(guò)網(wǎng)絡(luò)來(lái)表達(dá)調(diào)用的語(yǔ)義和傳達(dá)調(diào)用的數(shù)據(jù)。

比如說(shuō),A服務(wù)器想調(diào)用B服務(wù)器上的一個(gè)方法:

User getUserByName(String userName)

1、建立通信

首先要解決通訊的問(wèn)題:即A機(jī)器想要調(diào)用B機(jī)器,首先得建立起通信連接。

主要是通過(guò)在客戶端和服務(wù)器之間建立TCP連接,遠(yuǎn)程過(guò)程調(diào)用的所有交換的數(shù)據(jù)都在這個(gè)連接里傳輸。連接可以是按需連接,調(diào)用結(jié)束后就斷掉,也可以是長(zhǎng)連接,多個(gè)遠(yuǎn)程過(guò)程調(diào)用共享同一個(gè)連接。

通常這個(gè)連接可以是按需連接(需要調(diào)用的時(shí)候就先建立連接,調(diào)用結(jié)束后就立馬斷掉),也可以是長(zhǎng)連接(客戶端和服務(wù)器建立起連接之后保持長(zhǎng)期持有,不管此時(shí)有無(wú)數(shù)據(jù)包的發(fā)送,可以配合心跳檢測(cè)機(jī)制定期檢測(cè)建立的連接是否存活有效),多個(gè)遠(yuǎn)程過(guò)程調(diào)用共享同一個(gè)連接。

2、服務(wù)尋址

要解決尋址的問(wèn)題,也就是說(shuō),A服務(wù)器上的應(yīng)用怎么告訴底層的RPC框架,如何連接到B服務(wù)器(如主機(jī)或IP地址)以及特定的端口,方法的名稱名稱是什么。

通常情況下我們需要提供B機(jī)器(主機(jī)名或IP地址)以及特定的端口,然后指定調(diào)用的方法或者函數(shù)的名稱以及入?yún)⒊鰠⒌刃畔?,這樣才能完成服務(wù)的一個(gè)調(diào)用。

可靠的尋址方式(主要是提供服務(wù)的發(fā)現(xiàn))是RPC的實(shí)現(xiàn)基石,比如可以采用Redis或者Zookeeper來(lái)注冊(cè)服務(wù)等等。

2.1、從服務(wù)提供者的角度看:

當(dāng)服務(wù)提供者啟動(dòng)的時(shí)候,需要將自己提供的服務(wù)注冊(cè)到指定的注冊(cè)中心,以便服務(wù)消費(fèi)者能夠通過(guò)服務(wù)注冊(cè)中心進(jìn)行查找;

當(dāng)服務(wù)提供者由于各種原因致使提供的服務(wù)停止時(shí),需要向注冊(cè)中心注銷停止的服務(wù);

服務(wù)的提供者需要定期向服務(wù)注冊(cè)中心發(fā)送心跳檢測(cè),服務(wù)注冊(cè)中心如果一段時(shí)間未收到來(lái)自服務(wù)提供者的心跳后,認(rèn)為該服務(wù)提供者已經(jīng)停止服務(wù),則將該服務(wù)從注冊(cè)中心上去掉。

2.2、從調(diào)用者的角度看:

服務(wù)的調(diào)用者啟動(dòng)的時(shí)候根據(jù)自己訂閱的服務(wù)向服務(wù)注冊(cè)中心查找服務(wù)提供者的地址等信息;

當(dāng)服務(wù)調(diào)用者消費(fèi)的服務(wù)上線或者下線的時(shí)候,注冊(cè)中心會(huì)告知該服務(wù)的調(diào)用者;

服務(wù)調(diào)用者下線的時(shí)候,則取消訂閱。

3、網(wǎng)絡(luò)傳輸

3.1、序列化

當(dāng)A機(jī)器上的應(yīng)用發(fā)起一個(gè)RPC調(diào)用時(shí),調(diào)用方法和其入?yún)⒌刃畔⑿枰ㄟ^(guò)底層的網(wǎng)絡(luò)協(xié)議如TCP傳輸到B機(jī)器,由于網(wǎng)絡(luò)協(xié)議是基于二進(jìn)制的,所有我們傳輸?shù)膮?shù)數(shù)據(jù)都需要先進(jìn)行序列化(Serialize)或者編組(marshal)成二進(jìn)制的形式才能在網(wǎng)絡(luò)中進(jìn)行傳輸。然后通過(guò)尋址操作和網(wǎng)絡(luò)傳輸將序列化或者編組之后的二進(jìn)制數(shù)據(jù)發(fā)送給B機(jī)器。

3.2、反序列化

當(dāng)B機(jī)器接收到A機(jī)器的應(yīng)用發(fā)來(lái)的請(qǐng)求之后,又需要對(duì)接收到的參數(shù)等信息進(jìn)行反序列化操作(序列化的逆操作),即將二進(jìn)制信息恢復(fù)為內(nèi)存中的表達(dá)方式,然后再找到對(duì)應(yīng)的方法(尋址的一部分)進(jìn)行本地調(diào)用(一般是通過(guò)生成代理Proxy去調(diào)用,

通常會(huì)有JDK動(dòng)態(tài)代理、CGLIB動(dòng)態(tài)代理、Javassist生成字節(jié)碼技術(shù)等),之后得到調(diào)用的返回值。

4、服務(wù)調(diào)用

B機(jī)器進(jìn)行本地調(diào)用(通過(guò)代理Proxy和反射調(diào)用)之后得到了返回值,此時(shí)還需要再把返回值發(fā)送回A機(jī)器,同樣也需要經(jīng)過(guò)序列化操作,然后再經(jīng)過(guò)網(wǎng)絡(luò)傳輸將二進(jìn)制數(shù)據(jù)發(fā)送回A機(jī)器,而當(dāng)A機(jī)器接收到這些返回值之后,則再次進(jìn)行反序列化操作,恢復(fù)為內(nèi)存中的表達(dá)方式,最后再交給A機(jī)器上的應(yīng)用進(jìn)行相關(guān)處理(一般是業(yè)務(wù)邏輯處理操作)。

通常,經(jīng)過(guò)以上四個(gè)步驟之后,一次完整的RPC調(diào)用算是完成了,另外可能因?yàn)榫W(wǎng)絡(luò)抖動(dòng)等原因需要重試等。

擴(kuò)展閱讀

史上最全?40?道?Dubbo?面試題及答案,看完碾壓面試官!

dubbo服務(wù)調(diào)試管理實(shí)用命令

Java中幾種常用的RPC框架介紹

一篇文章了解RPC框架原理

Java 動(dòng)態(tài)代理及 RPC 框架介紹

BAT都是如何面試的?看完我驚呆了!

來(lái)源:https://blog.csdn.net/weixin_43822607/article/details/88799374

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容