日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别

發布時間:2023/11/28 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 基本概念

PRC 遠程過程調用 Remote Procedure Call,其就是一個節點請求另外一個節點提供的服務。當兩個物理分離的子系統需要建立邏輯上的關聯時,RPC 是牽線搭橋的常見技術手段之一。除 RPC 之外,常見的多系統數據交互方案還有分布式消息隊列、HTTP 請求調用、數據庫和分布式緩存等。

  • 本地過程調用:
    如果要將本地的對象進行相關操作,可以定義一個方法,然后將相關對象傳入,然后對其對象進行更新,然后由函數返回更新后的函數對象。

  • 遠程過程調用:
    在上述過程中,如果其定義的函數是在另外一個服務器端,并且執行的函數體也是在另外一臺遠程服務器上,那么這個過程就稱之為遠程過程調用。

2. 調用過程

其調用過程如下所示:

  1. 首先客戶端需要告訴服務器端,需要調用的函數,然后這里的函數和進程 ID 存在一個映射,客戶端遠程調用的時候,需要查詢一下函數,找到對應的 ID,然后執行對應函數的代碼。
  2. 客戶端需要把本地參數傳遞給遠程函數,在本地調用的過程中,會通過把參數轉換為字節碼,然后再傳遞給服務端,最后服務端再轉換為自身可以讀取的格式,這是一個序列化和反序列的過程。
  3. 轉換完成數據以后,在進行傳輸的過程一般是使用 HTTPSocket 協議進行傳輸。

除去 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 風格是 RPCREST,常用的媒體類型是 JSONXMLProtobuf。在 Go API 開發中常用的組合是 gRPC+ProtobufREST+JSON

其實業界普遍采用的做法是,內部系統之間調用用 RPC,對外用 REST,因為內部系統之間可能調用很頻繁,需要 RPC 的高性能支撐。對外用 REST 更易理解,更通用些。當然以現有的服務器性能,如果兩個系統間調用不是特別頻繁,對性能要求不是非常高,REST 的性能完全可以滿足。

HTTP 調用其實也是一種特殊的 RPC

HTTP1.0 協議時,HTTP 調用還只能是短鏈接調用,一個請求來回之后連接就會關閉。HTTP1.1HTTP1.0 協議的基礎上進行了改進,引入了 KeepAlive 特性可以保持 HTTP 連接長時間不斷開,以便在同一個連接之上進行多次連續的請求,進一步拉近了 HTTPRPC 之間的距離。

HTTP 協議進化到 2.0 之后,Google 開源了一個建立在 HTTP2.0 協議之上的通信框架直接取名為 gRPC,也就是 Google RPC

3. 解決問題

總之,RPC 解決掉了在分布式系統之中,服務之間調用的問題。讓服務在遠程調用的時候,能夠像本地調用一樣非常方便,并且讓調用者感知不到遠程調用的具體邏輯。
?
RPC 只是對底層通信和交互協議的一個封裝,便于上層使用。

4. 調用流程

一般來說調用過程如下所示:

  1. 調用者,以本地調用方式發起調用。
  2. Client stub 客戶端收到調用以后,將會把被調用的方法名,參數進行打包編碼成為特定的格式,包裝成為能夠被網絡傳輸的消息體。
  3. Client stub 將消息體通過網絡發送給服務端。
  4. Server stub 將會收到通過網絡接收到的消息后按照相應的格式進行拆分,獲取方法名稱和及其調用傳入的參數。
  5. 被調用者 Server 本地調用執行后將會把結果返回給 Server stub
  6. Server stub 將會將返回值打包編碼成為消息,然后通過網絡發送給客戶端。
  7. Client stub 收到消息以后,將會進行拆分,然后返回給 CLient
  8. Client 最終獲得本地 RPC 調用結果。

RPC 傳輸控制

對于消息數據的傳輸,主要有 HTTP 傳輸和 TCP 傳輸,一般來說 RPC 使用 TCP 進行傳輸,因為 TCP其要優于 HTTP 傳輸。
?
傳輸過程如下圖所示:
?
傳輸的時候一般通過 Socket 接口進行傳輸,也有使用 HTTP 作為底層的傳輸的結果,但是使用 HTTP 傳輸的比較少。
?

其過程如下:

  1. Server 發起創建套接字請求。
  2. 創建套接字后綁定相關端口
  3. 監聽鏈接
  4. 進入接收連接狀態中。
  5. Client 端創建套接字
  6. Client 端和 Server 端剛剛建立完成的 Socket 進行連接的建立。
  7. Server 端進行讀取,Client 進行數據寫。
  8. Client 端進行數據讀取,
  9. 雙方交換完數據以后,關閉連接。

?
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. 遠程調用時序圖

  1. 本地 RPCTest 類,將會調用 ServiceProducer 在服務端注冊并啟動 Server
  2. Server 將會調用 registerstart 進行初始化應用。
  3. RPCTest 將會通過 Client 調用本地方法。
  4. Client 將會調用遠程服務器方法 ServiceProducer 并傳入本地闡述,將消息發送給 Server端。
  5. Server 端放過反射,壓入 ServerTask
  6. ServerTask 將會遠程執行方法。
  7. 最后調用棧,調用完成以后,將結果返回給 Server
  8. Server 通過網絡傳輸信息到 Client
  9. Client 把結果最終返回給 RPCTest

總結

以上是生活随笔為你收集整理的RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。