文章目錄
- 對比 HTTP-REST 與 gRPC:各自的優缺點以及適用的場景
- HTTP-REST 與 gRPC 的核心區別
- gRPC 的優缺點
- HTTP-REST 的優缺點
- 適用場景
- 模糊點
- 什么是 Protobuf?
- HTTP/2 會將 HTTP 消息拆分并封裝為二進制幀,那還能過使用 HTTP/2 構建 RESTful 接口嗎?
- 如果 HTTP/2 支持 RESTful 接口,那為什么還需要 gRPC 呢?
對比 HTTP-REST 與 gRPC:各自的優缺點以及適用的場景
最近在總結近期學習的一個使用 gRPC + Gin 寫的 Golang 微服務項目,微服務的框架選用的是 gRPC,它是 RPC 的一種,可以讓客戶端像是在調用本地函數一樣對遠程服務器當中的函數進行調用。
通過對該項目進行學習,我個人感覺 gRPC 與 HTTP-REST 所做的工作非常的相似,即根據發起的請求,返回相應的結果,因此對二者的區別進行了詳細的調研,通過本篇文章進行簡要的總結。
HTTP-REST 與 gRPC 的核心區別
特性 | gRPC | HTTP |
---|---|---|
協議 | 基于 HTTP/2 通信 | 通常基于 HTTP/1.1,但也可以使用 HTTP/2 |
數據格式 | 默認使用 Protobuf 進行字節流的序列化與反序列化 | 通常使用 JSON/XML |
通信模式 | 支持單向、雙向流式通信 | 僅支持請求-響應,無流式 |
性能 | 高(二進制編碼 + HTTP/2 多路復用) | 較低(文本解析 + HTTP/1.1 的無多路復用) |
適用場景 | 微服務之間的通信、實時流式數據 | Web API(返回 RESTful API 的數據給前端)、瀏覽器兼容場景 |
gRPC 的優缺點
?優點
- 高性能:Protobuf 序列化和反序列化的編碼體積小,使用 HTTP/2 傳輸降低延遲;
- 流式支持:適合實時數據傳輸(聊天、日志流);
- 強類型接口:通過
.proto
文件明確定義服務和方法; - 跨語言支持:自動生成多客戶端語言。
?缺點
- 瀏覽器支持差:需要 gRPC-Web 代理;
- 調試復雜:二進制數據需要經過轉換才能為人所閱讀;
- 生態工具較少:與 HTTP-REST 相比,gRPC 的工具鏈尚不成熟。
HTTP-REST 的優缺點
?優點
- 通用性強:所有語言和平臺(甚至是 IoT)原生支持;
- 可讀性好:使用 JSON/XML 格式進行數據傳輸,便于接口調試和日志記錄;
- 瀏覽器友好:直接用于前端調用。
?缺點
- 性能較低:基于純文本進行傳輸的效率較低,對純文本進行解析的成本也較高;
- 無流式支持:HTTP-REST 僅支持通過請求-響應模式請求資源,不支持流式傳輸;
- 弱類型約束:接口規范依賴于文檔。
適用場景
gRPC(HTTP/2 + Protobuf)
更適用于微服務之間的通信以及流式數據傳輸。
HTTP-REST(HTTP/1.1 或 HTTP/2 + JSON)
- 瀏覽器直接調用 API:如果使用 gRPC 則還需要 gRPC-web 進行代理,但是如果此時使用 HTTP-REST 可以直接獲得 JSON 格式的數據;
- 快速原型開發:JSON 很容易手動構造,而 protobuf 則需要編譯
.proto
文件; - 兼容舊系統:遺留系統可能不支持 gRPC,但基本都支持 HTTP + JSON。
模糊點
根據以上內容的總結,我產生了一些模糊點,在此列舉并深入研究一下。
什么是 Protobuf?
Protobuf(Protocol Buffers)可以被理解為一種高效的數據序列化與反序列化協議,它的核心作用是將結構化的數據(如對象或消息)轉換為二進制格式(序列化),或將字節流當中的二進制數據轉換為原始數據(反序列化)。
如果想要使用 gRPC 來建立微服務,那么所編寫的 proto 文件很有可能包含 service 和 message 兩部分,service 當中定義了具體的遠程過程調用函數,而 message 定義了 RPC 函數的請求結構體和響應結構體。
? Protobuf 的優點
- 高性能:二進制編碼體積小,網絡傳輸與序列化和反序列化的時間開銷隨之降低;
- 強類型與模式化:通過 proto 文件定義數據結構,避免運行時錯誤;
- 跨語言支持:protobuf 官方支持多種語言,生成的代碼接口一致。
? Protobuf 的缺點
- 需要預編譯:必須先定義 proto 文件并編譯生成相應語言的代碼,靈活性低于 JSON;
- 可讀性差:二進制數據不能直接閱讀,如需調試需要借助工具;
- 不適合所有場景:比如瀏覽器直接處理 Protobuf 格式的數據非常復雜,對于 gRPC 而言還需要借助 gRPC-web 代理才能過讀取,瀏覽器場景更適合直接使用 JSON 進行序列化與反序列化。
💡 Protobuf 的常見使用場景
- 微服務通信:gRPC 默認使用 Protobuf 通信,替代 REST + JSON;
- 高性能存儲:如數據庫緩存、日志存儲;
- 跨語言數據交換:不同語言服務間傳遞結構化數據(當然這一點基于 JSON 也能做到)。
HTTP/2 會將 HTTP 消息拆分并封裝為二進制幀,那還能過使用 HTTP/2 構建 RESTful 接口嗎?
完全可以。因為 HTTP/2 只是 HTTP 協議的一個版本,它將 HTTP 消息(Header + Body)拆分為二進制幀只是為了優化傳輸效率(多路復用、頭部壓縮),但不改變 HTTP 的語義。
具體來說,應用層的原始數據(比如 JSON 或 XML,也可以是 Protobuf)不會被拆分為二進制幀,HTTP/2 將數據轉為二進制的時機是在將應用層數據通過傳輸層發送之前。在傳輸層發送字節流之前,HTTP/2 會將 HTTP 消息(Header + Body)拆分并封裝為二進制幀,從而管理多路復用和優先級,提升了傳輸以及序列化反序列化的效率。
如果 HTTP/2 支持 RESTful 接口,那為什么還需要 gRPC 呢?
雖然 HTTP/2 本身已經優化了傳輸效率,但是 gRPC 基于 HTTP/2 進行了進一步的優化,具體體現在使用 Protobuf 作為數據的編碼形式,為 HTTP/2 引入了強類型約束,并且具有高性能和跨語言的特性。
此外,HTTP/2 + REST-JSON 僅支持請求-響應模式,無法實現持續的數據流。
而 gRPC 原生支持 4 種通信模式:
- Unary RPC(類似 REST,單一請求-響應);
- Server Streaming RPC(服務端推送流,比如實時日志);
- Client Streaming RPC(客戶端上傳流,如文件分塊上傳);
- Bidirectional Streaming RPC(雙向流,如聊天應用)。