RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别
1. 基本概念
PRC 遠程過程調用 Remote Procedure Call,其就是一個節點請求另外一個節點提供的服務。當兩個物理分離的子系統需要建立邏輯上的關聯時,RPC 是牽線搭橋的常見技術手段之一。除 RPC 之外,常見的多系統數據交互方案還有分布式消息隊列、HTTP 請求調用、數據庫和分布式緩存等。
-
本地過程調用:
如果要將本地的對象進行相關操作,可以定義一個方法,然后將相關對象傳入,然后對其對象進行更新,然后由函數返回更新后的函數對象。 -
遠程過程調用:
在上述過程中,如果其定義的函數是在另外一個服務器端,并且執行的函數體也是在另外一臺遠程服務器上,那么這個過程就稱之為遠程過程調用。
2. 調用過程
其調用過程如下所示:
- 首先客戶端需要告訴服務器端,需要調用的函數,然后這里的函數和進程
ID存在一個映射,客戶端遠程調用的時候,需要查詢一下函數,找到對應的ID,然后執行對應函數的代碼。 - 客戶端需要把本地參數傳遞給遠程函數,在本地調用的過程中,會通過把參數轉換為字節碼,然后再傳遞給服務端,最后服務端再轉換為自身可以讀取的格式,這是一個序列化和反序列的過程。
- 轉換完成數據以后,在進行傳輸的過程一般是使用
HTTP,Socket協議進行傳輸。
除去 RPC 調用以外,還有 RESTful API 進行調用。RESTful API 調用其示例圖如下圖所示:
?
在上圖中,一個服務 A 如果訪問另外一個服務器下的 B,這個過程采用的就是 RESTful API 進行數據的傳輸。并且兩個過程的數據會進行序列化和反序列化炒作。
?
兩種方式進行對比而言,
RPC通信代價比較低,因為RPC是直接基于TCP進行調用的,并且傳輸的數據都是基于TCP進行的,所以效率更高,更優。但是由于是基于TCP的所以實現起來更為的復雜,更為的難以維護。- 而
RESTful API由于是直接基于HTTP的所以實現更為簡單,維護更為容易。 RPC快,效率高,但是不夠通用,就好比地方方言,HTTP通用是普通話,但是效率不夠高,傳輸的字節內容冗余多。REST相對更規范,更標準,更通用,簡單易用,維護性和擴展性都比較好。RPC+Protobuf采用的是TCP做傳輸協議,REST直接使用HTTP做應用層協議,這種區別導致REST在調用性能上會比RPC+Protobuf低。
Go 語言中常用的 API 風格是 RPC 和 REST,常用的媒體類型是 JSON、XML 和 Protobuf。在 Go API 開發中常用的組合是 gRPC+Protobuf 和 REST+JSON。
其實業界普遍采用的做法是,內部系統之間調用用 RPC,對外用 REST,因為內部系統之間可能調用很頻繁,需要 RPC 的高性能支撐。對外用 REST 更易理解,更通用些。當然以現有的服務器性能,如果兩個系統間調用不是特別頻繁,對性能要求不是非常高,REST 的性能完全可以滿足。
HTTP 調用其實也是一種特殊的 RPC。
HTTP1.0 協議時,HTTP 調用還只能是短鏈接調用,一個請求來回之后連接就會關閉。HTTP1.1 在 HTTP1.0 協議的基礎上進行了改進,引入了 KeepAlive 特性可以保持 HTTP 連接長時間不斷開,以便在同一個連接之上進行多次連續的請求,進一步拉近了 HTTP 和 RPC 之間的距離。
當 HTTP 協議進化到 2.0 之后,Google 開源了一個建立在 HTTP2.0 協議之上的通信框架直接取名為 gRPC,也就是 Google RPC。
3. 解決問題
總之,RPC 解決掉了在分布式系統之中,服務之間調用的問題。讓服務在遠程調用的時候,能夠像本地調用一樣非常方便,并且讓調用者感知不到遠程調用的具體邏輯。
?
RPC 只是對底層通信和交互協議的一個封裝,便于上層使用。
4. 調用流程
一般來說調用過程如下所示:
- 調用者,以本地調用方式發起調用。
Client stub客戶端收到調用以后,將會把被調用的方法名,參數進行打包編碼成為特定的格式,包裝成為能夠被網絡傳輸的消息體。Client stub將消息體通過網絡發送給服務端。Server stub將會收到通過網絡接收到的消息后按照相應的格式進行拆分,獲取方法名稱和及其調用傳入的參數。- 被調用者
Server本地調用執行后將會把結果返回給Server stub。 Server stub將會將返回值打包編碼成為消息,然后通過網絡發送給客戶端。Client stub收到消息以后,將會進行拆分,然后返回給CLient。Client最終獲得本地RPC調用結果。
RPC 傳輸控制
對于消息數據的傳輸,主要有 HTTP 傳輸和 TCP 傳輸,一般來說 RPC 使用 TCP 進行傳輸,因為 TCP其要優于 HTTP 傳輸。
?
傳輸過程如下圖所示:
?
傳輸的時候一般通過 Socket 接口進行傳輸,也有使用 HTTP 作為底層的傳輸的結果,但是使用 HTTP 傳輸的比較少。
?
其過程如下:
Server發起創建套接字請求。- 創建套接字后綁定相關端口
- 監聽鏈接
- 進入接收連接狀態中。
Client端創建套接字Client端和Server端剛剛建立完成的Socket進行連接的建立。Server端進行讀取,Client進行數據寫。Client端進行數據讀取,- 雙方交換完數據以后,關閉連接。
?
Server 端代碼示例:
import socketsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("localhost", 8080))
sock.listen(1) # 監聽客戶端連接
while True:conn, addr = sock.accept() # 接收一個客戶端連接print(conn.recv(1024))conn.sendall(b"world") # 將響應發送到發送緩沖 send bufferconn.close()
輸出結果
b'hello'
Client 端代碼示例:
import socketsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("localhost", 8080))
sock.sendall(b"hello") # 將消息輸出到發送緩沖 send buffer
print(sock.recv(1024))
sock.close()
輸出結果
b'world'
問題:客戶端瘋狂發送請求,但是服務器不讀不處理,會發生什么?
- 如果接收和發送隊列沒有設置大小,服務器處理能力弱,
tcp會動態調整直至耗盡整個內存; - 設置了大小,
socket緩沖區滿,那么socket會出現阻塞,不接受發送端的消息; - 如果發送的請求
size大于發送和接收隊列之和,那么會一直阻塞下去;
5. 遠程調用時序圖
- 本地
RPCTest類,將會調用ServiceProducer在服務端注冊并啟動Server。 Server將會調用register和start進行初始化應用。RPCTest將會通過Client調用本地方法。Client將會調用遠程服務器方法ServiceProducer并傳入本地闡述,將消息發送給Server端。Server端放過反射,壓入ServerTask。ServerTask將會遠程執行方法。- 最后調用棧,調用完成以后,將結果返回給
Server。 Server通過網絡傳輸信息到Client。Client把結果最終返回給RPCTest。
總結
以上是生活随笔為你收集整理的RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国电竞椅行业市场行
- 下一篇: RPC 笔记(03)— gRPC 概念、