面試准備——rpc面試題


https://www.jianshu.com/p/28e48e5f9c73

1 什么是 RPC ?

  • RPC (Remote Procedure Call)即遠程過程調用,是分布式系統常見的一種通信方法。它允許程序調用另一個地址空間(通常是共享網絡的另一台機器上)的過程或函數,而不用程序員顯式編碼這個遠程調用的細節。
  • 除 RPC 之外,常見的多系統數據交互方案還有分布式消息隊列、HTTP 請求調用、數據庫和分布式緩存等。
  • 其中 RPC 和 HTTP 調用是沒有經過中間件的,它們是端到端系統的直接數據交互。

簡單的說

  • RPC就是從一台機器(客戶端)上通過參數傳遞的方式調用另一台機器(服務器)上的一個函數或方法(可以統稱為服務)並得到返回的結果。
  • RPC會隱藏底層的通訊細節(不需要直接處理Socket通訊或Http通訊)。
  • 客戶端發起請求,服務器返回響應(類似於Http的工作方式)RPC在使用形式上像調用本地函數(或方法)一樣去調用遠程的函數(或方法)。

2 為什么我們要用RPC?

RPC 的主要目標是讓構建分布式應用更容易,在提供強大的遠程調用能力時不損失本地調用的語義簡潔性。為實現該目標,RPC 框架需提供一種透明調用機制讓使用者不必顯式的區分本地調用和遠程調用。

3 RPC需要解決的三個問題

RPC要達到的目標:遠程調用時,要能夠像本地調用一樣方便,讓調用者感知不到遠程調用的邏輯。

  • Call ID映射。我們怎么告訴遠程機器我們要調用哪個函數呢?在本地調用中,函數體是直接通過函數指針來指定的,我們調用具體函數,編譯器就自動幫我們調用它相應的函數指針。但是在遠程調用中,是無法調用函數指針的,因為兩個進程的地址空間是完全不一樣。所以,在RPC中,所有的函數都必須有自己的一個ID。這個ID在所有進程中都是唯一確定的。客戶端在做遠程過程調用時,必須附上這個ID。然后我們還需要在客戶端和服務端分別維護一個 {函數 <--> Call ID} 的對應表。兩者的表不一定需要完全相同,但相同的函數對應的Call ID必須相同。當客戶端需要進行遠程調用時,它就查一下這個表,找出相應的Call ID,然后把它傳給服務端,服務端也通過查表,來確定客戶端需要調用的函數,然后執行相應函數的代碼。
  • 序列化和反序列化。客戶端怎么把參數值傳給遠程的函數呢?在本地調用中,我們只需要把參數壓到棧里,然后讓函數自己去棧里讀就行。但是在遠程過程調用時,客戶端跟服務端是不同的進程,不能通過內存來傳遞參數。甚至有時候客戶端和服務端使用的都不是同一種語言(比如服務端用C++,客戶端用Java或者Python)。這時候就需要客戶端把參數先轉成一個字節流,傳給服務端后,再把字節流轉成自己能讀取的格式。這個過程叫序列化和反序列化。同理,從服務端返回的值也需要序列化反序列化的過程。
  • 網絡傳輸。遠程調用往往是基於網絡的,客戶端和服務端是通過網絡連接的。所有的數據都需要通過網絡傳輸,因此就需要有一個網絡傳輸層。網絡傳輸層需要把Call ID和序列化后的參數字節流傳給服務端,然后再把序列化后的調用結果傳回客戶端。只要能完成這兩者的,都可以作為傳輸層使用。因此,它所使用的協議其實是不限的,能完成傳輸就行。盡管大部分RPC框架都使用TCP協議,但其實UDP也可以,而gRPC干脆就用了HTTP2。Java的Netty也屬於這層的東西。

4 實現高可用RPC框架需要考慮到的問題

  • 既然系統采用分布式架構,那一個服務勢必會有多個實例,要解決如何獲取實例的問題。所以需要一個服務注冊中心,比如在Dubbo中,就可以使用Zookeeper作為注冊中心,在調用時,從Zookeeper獲取服務的實例列表,再從中選擇一個進行調用;
  • 如何選擇實例呢?就要考慮負載均衡,例如dubbo提供了4種負載均衡策略;
  • 如果每次都去注冊中心查詢列表,效率很低,那么就要加緩存;
  • 客戶端總不能每次調用完都等着服務端返回數據,所以就要支持異步調用;
  • 服務端的接口修改了,老的接口還有人在用,這就需要版本控制;
  • 服務端總不能每次接到請求都馬上啟動一個線程去處理,於是就需要線程池;

5 理論結構模型

RPC 服務端通過RpcServer去導出(export)遠程接口方法,而客戶端通過RpcClient去導入(import)遠程接口方法。客戶端像調用本地方法一樣去調用遠程接口方法,RPC 框架提供接口的代理實現,實際的調用將委托給代理RpcProxy。代理封裝調用信息並將調用轉交給RpcInvoker去實際執行。在客戶端的RpcInvoker通過連接器RpcConnector去維持與服務端的通道RpcChannel,並使用RpcProtocol執行協議編碼(encode)並將編碼后的請求消息通過通道發送給服務端。

RPC 服務端接收器RpcAcceptor接收客戶端的調用請求,同樣使用RpcProtocol執行協議解碼(decode)。

解碼后的調用信息傳遞給RpcProcessor去控制處理調用過程,最后再委托調用給RpcInvoker去實際執行並返回調用結果。


主流的RPC框架

服務治理型

  • dubbo:是阿里巴巴公司開源的一個Java高性能優秀的服務框架,使得應用可通過高性能的 RPC 實現服務的輸出和輸入功能,可以和 Spring框架無縫集成。dubbo 已經與12年年底停止維護升級。
  • dubbox:是當當團隊基於dubbo升級的一個版本。是一個分布式的服務架構,可直接用於生產環境作為SOA服務框架。dubbox資源鏈接
  • motan:是新浪微博開源的一個Java框架。它誕生的比較晚,起於2013年,2016年5月開源。Motan 在微博平台中已經廣泛應用,每天為數百個服務完成近千億次的調用。motan資源鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM