如何在 Apinto 實現 HTTP 與gRPC 的協議轉換 (上)

小Kit發表於2023-03-16


什麼是 gRPC

gRPC是由google開發的一個高效能、通用的開源 RPC 框架,主要面向移動應用開發且基於HTTP/2協議標準而設計,同時支援大多數流行的程式語言。

gRPC基於 HTTP/2 協議傳輸,而 HTTP/2 相比 HTTP1.x有以下優勢:

  1. 採用二進位制格式傳輸協議,支援多路複用;

  2. 支援透過同一個連線傳送多個併發的請求,支援流式傳輸;

  3. 伺服器可以對客戶端的一個請求傳送多個響應;

  4. 對訊息頭進行了壓縮傳輸,能夠節省訊息頭佔用的網路流量。
    gRPC 使用 Protocol Buffers 作為序列化協議。

但同時,gRPC 也有自身的侷限性:

1)瀏覽器支援有限:

當下,不可能直接從瀏覽器呼叫 gRPC 服務。gRPC 大量使用 HTTP/2 功能,沒有瀏覽器提供支援 gRPC 客戶機的 Web 請求所需的控制級別。例如,瀏覽器不允許呼叫者要求使用的 HTTP/2 ,或者提供對底層 HTTP/2 框架的訪問。

2)不是人類可讀的:

HTTP API 請求以文字形式傳送,可以由人讀取和建立。預設情況下, gRPC 訊息使用 protobuf 編碼。雖然 protobuf 的傳送和接收效率很高,但它的二進位制格式是不可讀的。protobuf 需要在 *.proto 檔案中指定的訊息介面描述才能正確反序列化。需要額外的工具來分析線路上的 Protobuf 有效負載,並手工編寫請求。

若需要將內部 gRPC 作為介面開放給外部使用者或瀏覽器呼叫,則需要有第三方代理解決 HTTP 協議轉換成 gRPC 協議的問題。

為此,我們在 Apinto 多協議支援的基礎上,釋出了 HTTPgRPC 外掛:(eolinker.com:apinto:http_to_grpc)


在 Apinto 上 HTTP 轉 gRPC 外掛

Apinto 透過外掛的方式支援 HTTP 協議轉換成 gRPC 協議請求,在http_to_grpc 外掛中完成了 HTTP 客戶端 與 gRPC``Server 通訊時的協議轉換及資料編解碼工作,其通訊的過程如下:

接下來透過一個完整的示例向大家演示怎樣構建一個 HTTP請求,並透過 Apinto 進行 HTTP協議 轉換成 gRPC協議請求。在以下的示例中,我們會將 Go 作為 gRPC``Server 服務端處理程式,使用 Eolink 作為 HTTP 客戶端,發起 HTTP 請求。

以下示例可以在 Apinto 倉庫中獲取。


配置 Protocol Buffer

1. 建立示例檔案 msg.proto

該檔案定義了示例訊息型別,我們在這裡定義了一個 HelloRequestHelloResponse 的 message。

2. 建立示例檔案 service.proto

該檔案定義了服務 Hello,引入了第一步建立的檔案 msg.proto,定義了四個方法,包含了一元 RPC、客戶端流、服務端流、雙向流四種 gRPC 通訊模式。


配置服務端程式

1. 建立自動生成 gRPC 檔案指令碼(grpc.sh)

該指令碼將生成 gRPC 客戶端/服務端呼叫相關程式碼,並將其儲存到 demo_service目錄下。

執行 grpc.sh,生成服務端 Go 原始訊息和服務/客戶端存根。


2. 實現服務端處理程式介面

上述程式碼重新定義了 Hello 方法:

HelloRequest 中的 name 欄位透過 HelloResponsemsg 欄位封裝成hello,%s 的結果返回

將請求的 Header 作為 gRPC 響應的 Trailer 頭部返回

3. 定義 gRPC 服務端入口檔案

在此處,gRPC 服務端開啟了 gRPC 反射,配置 Apinto 閘道器時,可選擇繫結具體的 Protobuf 資源,也可以直接啟用反射,動態獲取 gRPC 服務端的 Protobuf 資訊。

4. 編譯 gRPC 伺服器程式

上文介紹瞭如何構造 gRPC 示例伺服器,下文將使用該示例伺服器,結合 Apinto-Dashboard 來演示如何將 HTTP 協議轉成 gRPC 。

更多使用方式可到我們的 Github 進一步瞭解:https://github.com/eolinker/apinto

相關文章