RPC簡介及原理介紹
背景
框架主要包括兩個:gRPC框架、go-micro框架。
首先來學習gRPC框架相關的內容。
本地過程調用
讓我們先來看看正常情況下程序的執行和調用情況。例如有如下go語言代碼:
func main() {
var a, b int
a = 1
b = 2
c := Add(a, b)
fmt.Println("計算結果:", c)
}
func Add(a int, b int) int {
return a + b
}
在上述的Go語言代碼中,我們定義了一個Add方法用於實現兩個數相加的功能,在main方法中通過調用Add方法實現了計算兩個變量之和的操作。整個過程涉及到變量值入棧,出棧,賦值等操作,最后將出棧的計算結果返回並賦值給c變量。
總結說來,本地程序調用的過程大致可以分為幾個步驟和階段:
- 開發者開發好的程序,並進行編譯,編譯成機器認可的可執行文件。
- 運行可執行文件,調用對應的功能方法,期間會讀取可執行文件中國的機器指令,進行入棧,出棧賦值等操作。此時,計算機由可執行程序所在的進程控制。
- 調用結束,所有的內存數據出棧,程序執行結束。計算機繼續由操作系統進行控制。
問題及解決方法
上文我們已經說過,遠程過程調用是在兩台或者多台不同的物理機器上實現的調用,其間要跨越網絡進行調用。因此,我們再想通過前文本地方法調用的形式完成功能調用,就無法實現了,因為編譯器無法通過編譯的可執行文件來調用遠程機器上的程序方法。因此需要采用RPC的方式來實現遠端服務器上的程序方法的調用。
RPC技術內部原理是通過兩種技術的組合來實現的:本地方法調用 和 網絡通信技術。
RPC簡介
在上述本地過程調用的例子中,我們是在一台計算機上執行了計算機上的程序,完成調用。隨着計算機技術的發展和需求場景的變化,有時就需要從一台計算機上執行另外一台計算機上的程序的需求,因此后來又發展出來了RPC技術。特別是目前隨着互聯網技術的快速迭代和發展,用戶和需求幾乎都是以指數式的方式在高速增長,這個時候絕大多數情況下程序都是部署在多台機器上,就需要在調用其他物理機器上的程序的情況。
RPC是Remote Procedure Call Protocol單詞首字母的縮寫,簡稱為:RPC,翻譯成中文叫遠程過程調用協議。所謂遠程過程調用,通俗的理解就是可以在本地程序中調用運行在另外一台服務器上的程序的功能方法。這種調用的過程跨越了物理服務器的限制,是在網絡中完成的,在調用遠端服務器上程序的過程中,本地程序等待返回調用結果,直到遠端程序執行完畢,將結果進行返回到本地,最終完成一次完整的調用。
需要強調的是:遠程過程調用指的是調用遠端服務器上的程序的方法整個過程。
RPC設計組成
RPC技術在架構設計上有四部分組成,分別是:客戶端、客戶端存根、服務端、服務端存根。
這里提到了客戶端和服務端的概念,其屬於程序設計架構的一種方式,在現代的計算機軟件程序架構設計上,大方向上分為兩種方向,分別是:B/S架構、C/S架構。B/S架構指的是瀏覽器到服務器交互的架構方式,另外一種是在計算機上安裝一個單獨的應用,稱之為客戶端,與服務器交互的模式。
由於在服務的調用過程中,有一方是發起調用方,另一方是提供服務方。因此,我們把服務發起方稱之為客戶端,把服務提供方稱之為服務端。以下是對RPC的四種角色的解釋和說明:
-
客戶端(Client):服務調用發起方,也稱為服務消費者。
-
客戶端存根(Client Stub):該程序運行在客戶端所在的計算機機器上,主要用來存儲要調用的服務器的地址,另外,該程序還負責將客戶端請求遠端服務器程序的數據信息打包成數據包,通過網絡發送給服務端Stub程序;其次,還要接收服務端Stub程序發送的調用結果數據包,並解析返回給客戶端。
-
服務端(Server):遠端的計算機機器上運行的程序,其中有客戶端要調用的方法。
-
服務端存根(Server Stub):接收客戶Stub程序通過網絡發送的請求消息數據包,並調用服務端中真正的程序功能方法,完成功能調用;其次,將服務端執行調用的結果進行數據處理打包發送給客戶端Stub程序。
RPC原理及調用步驟
了解完了RPC技術的組成結構我們來看一下具體是如何實現客戶端到服務端的調用的。實際上,如果我們想要在網絡中的任意兩台計算機上實現遠程調用過程,要解決很多問題,比如:
- 兩台物理機器在網絡中要建立穩定可靠的通信連接。
- 兩台服務器的通信協議的定義問題,即兩台服務器上的程序如何識別對方的請求和返回結果。也就是說兩台計算機必須都能夠識別對方發來的信息,並且能夠識別出其中的請求含義和返回含義,然后才能進行處理。這其實就是通信協議所要完成的工作。
讓我們來看看RPC具體是如何解決這些問題的,RPC具體的調用步驟圖如下:
在上述圖中,通過1-10的步驟圖解的形式,說明了RPC每一步的調用過程。具體描述為:
-
1、客戶端想要發起一個遠程過程調用,首先通過調用本地客戶端Stub程序的方式調用想要使用的功能方法名;
-
2、客戶端Stub程序接收到了客戶端的功能調用請求,將客戶端請求調用的方法名,攜帶的參數等信息做序列化操作,並打包成數據包。
-
3、客戶端Stub查找到遠程服務器程序的IP地址,調用Socket通信協議,通過網絡發送給服務端。
-
4、服務端Stub程序接收到客戶端發送的數據包信息,並通過約定好的協議將數據進行反序列化,得到請求的方法名和請求參數等信息。
-
5、服務端Stub程序准備相關數據,調用本地Server對應的功能方法進行,並傳入相應的參數,進行業務處理。
-
6、服務端程序根據已有業務邏輯執行調用過程,待業務執行結束,將執行結果返回給服務端Stub程序。
-
7、服務端Stub程序將程序調用結果按照約定的協議進行序列化,並通過網絡發送回客戶端Stub程序。
-
8、客戶端Stub程序接收到服務端Stub發送的返回數據,對數據進行反序列化操作,並將調用返回的數據傳遞給客戶端請求發起者。
-
9、客戶端請求發起者得到調用結果,整個RPC調用過程結束。
RPC涉及到的相關技術
通過上文一系列的文字描述和講解,我們已經了解了RPC的由來和RPC整個調用過程。我們可以看到RPC是一系列操作的集合,其中涉及到很多對數據的操作,以及網絡通信。因此,我們對RPC中涉及到的技術做一個總結和分析:
-
1、動態代理技術: 上文中我們提到的Client Stub和Sever Stub程序,在具體的編碼和開發實踐過程中,都是使用動態代理技術自動生成的一段程序。
-
2、序列化和反序列化: 在RPC調用的過程中,我們可以看到數據需要在一台機器上傳輸到另外一台機器上。在互聯網上,所有的數據都是以字節的形式進行傳輸的。而我們在編程的過程中,往往都是使用數據對象,因此想要在網絡上將數據對象和相關變量進行傳輸,就需要對數據對象做序列化和反序列化的操作。
-
序列化:把對象轉換為字節序列的過程稱為對象的序列化,也就是編碼的過程。
-
反序列化:把字節序列恢復為對象的過程稱為對象的反序列化,也就是解碼的過程。
-
我們常見的Json,XML等相關框架都可以對數據做序列化和反序列化編解碼操作。