gRPC 爲什麼比基於 JSON 的 REST API 快
兩個主要原因。
看了不少關於 REST 與 JSON 和 gRPC 的性能基準測試。其中一些測試顯示,gRPC 將每個請求的延遲減少了一半。
那麼,它爲什麼這麼快呢?🤔
⚡ 第一個原因是 HTTP/2。
HTTP/1.1 的請求和響應是同步的,一次只能處理一個請求。而 HTTP/2 請求是異步的,可以同時發送多個請求,不需要等待前一個請求的響應。減少了等待前一個請求完成的時間,同時連接複用,也避免了 TCP 和 TLS 握手的時間。
這對 gRPC 來說是一個重要因素,因爲 gRPC 在底層利用了 HTTP/2 協議。
雖然對用戶來說可能看起來只是簡單的 RPC 調用,但它在底層使用的是 HTTP。
📦 第二個原因是 Protobuf。
HTTP/2 + JSON 本身就可以相當快,但使用 Protobuf 代替 JSON 可以進一步推動性能提升。
像 JSON 一樣,Protobuf 是一種用於交換數據的結構化消息格式,但最大的不同是 Protobuf 是基於二進制的。
作爲基於二進制的,Protobuf 在網絡傳輸數據時更加緊湊。
以下是一個簡單的對比示例。
假設我們有一個表示用戶信息的結構:
{
"id": 12345,
"name": "Alice",
"email": "alice@example.com",
"isAdmin": true,
"scores": [85, 92, 88]
}
對應的 Protobuf 定義如下:
syntax = "proto3";
message User {
int32 id = 1;
string name = 2;
string email = 3;
bool isAdmin = 4;
repeated int32 scores = 5;
}
數據編碼後的對比
我們將上述數據分別序列化爲 JSON 和 Protobuf,得到如下結果:
- JSON 格式
序列化後的 JSON 數據如下(未壓縮):
{
"id": 12345,
"name": "Alice",
"email": "alice@example.com",
"isAdmin": true,
"scores": [85, 92, 88]
}
JSON 字符串的總大小爲 115 字節。
- Protobuf 格式
序列化後的 Protobuf 數據(二進制形式,無法直接閱讀,但可以解析爲字節數組表示):
08 b9 60 12 05 41 6c 69 63 65 1a 12 61 6c 69 63 65 40 65 78 61 6d 70 6c 65 2e 63 6f 6d 20 01 2a 03 55 5c 58
Protobuf 字節數組的總大小爲 37 字節。
JSON 採用了文本格式,包含大量描述性的標籤(如 "id"、"name" 等)以及符號(如引號、逗號等),如果有 json 字符串的嵌套可能還有一堆的斜槓。而二進制格式,無需描述性標籤,僅包含數據和簡潔的字段標識符(字段 ID)。
Protobuf 使用二進制編碼和字段號(如 id = 1)來標識數據,而 JSON 使用鍵值對字符串描述數據結構,增加了額外開銷。所以,Protobuf 的數據大小顯著小於 JSON,尤其是字段較多、數據量較大時,差距會更明顯。
因此,在帶寬敏感或高性能需求的場景中,Protobuf 優勢突出。
而且 Protobuf 在序列化和反序列化過程中也比 JSON 快得多。據測試顯示 Protobuf 序列化速度比 JSON 快 10 到 100 倍。
JSON 需要解析文本中的每個字符,尤其是長字符串和數字字段時,會面臨較高的開銷。解析 JSON 數據時,必須將文本解析爲原始數據類型,並且每次解析時需要處理字符串鍵名、符號(如括號、逗號等),這比直接解析二進制數據慢得多。
因此,Protobuf 不僅傳輸速度更快,而且處理速度也更快。
💎 但性能並非沒有代價。
雖然 gRPC 有很多優勢,甚至超越了性能,它也帶來了一些複雜性。
🔀 複雜性:負載分配
和 HTTP/2 一樣,gRPC 默認會爲多個請求重用連接。如果主要依賴基於連接的負載均衡,這種多路複用可能導致負載分配不均衡。
使用第七層負載均衡器或客戶端負載均衡可以解決這個問題,但需要考慮這一點。
🧰 複雜性:故障排除
雖然用於故障排除 gRPC 服務的工具集正在增長,但它仍然不如 REST + JSON 那樣容易。
gRPC 使得執行臨時請求、捕獲和調試有效載荷、驗證端點等變得更加困難。
📄 複雜性:契約
Protobuf 的一個優勢是清晰的契約。每個人都使用相同的 proto 文件來生成序列化和反序列化的包。
這種方法很棒,因爲它消除了誤解,但在分發和版本控制該文件時可能會變得複雜,尤其是當試圖將其分發給外部用戶時。
💡 總結
如果你需要性能提升,或者你的環境能夠處理 gRPC 帶來的複雜性,那麼 gRPC 是一個很好的方法。
如果你對 REST + JSON 感到滿意,並且對 gRPC 的複雜性感到困擾,那也沒關係;REST 依然很多人在使用。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/-LwAhWBy9y0dkzFbIB9YQA