Protobuf 是技術魔人公司 Google 內部孵化後開源造福社會的專案,從簡單內部協議緩衝區 (Protocol Buffer) 開始發展,因此得名 Protobuf,後來被魔改加上一堆功能早就不是當年的緩衝資料區,不過基於歷史因素還是保留了緩衝區在名字中。
2001 V1 正式面世,後來經歷兩次大改版,現在流通的以 V3 版本為主,不過大部分框架都在 V1 時期就奠定基礎了。
<Order>
<Id>123</Id>
<UserId>42</UserId>
<Items>
<Item>
<Sku>9001</Sku>
<Qty>2</Qty>
</Item>
</Items>
<Status>PAID</Status>
<CreatedAtUnix>1726286400</CreatedAtUnix>
</Order>
message Order {
int64 id = 1;
int64 user_id = 2;
repeated Item items = 3;
Status status = 4;
int64 created_at_unix = 5;
message Item { int64 sku = 1; int32 qty = 2; }
enum Status { STATUS_UNSPECIFIED = 0; PAID = 2; }
}
面向 | JSON | Protobuf | XML |
---|---|---|---|
資料格式 | 文字,可閱讀 | 二進位,不可直接閱讀 | 文字,可閱讀,標記語法豐富 |
體積 | 中 | 小(約較 JSON 減少 10–30 倍) | 大(標籤冗長) |
序列化與解析效能 | 中 | 高 | 低到中(DOM/SAX 成本較高) |
結構與型別約束 | 弱,需額外驗證或 JSON Schema | 強,.proto 強制型別與欄位 | 可用 XSD,但較複雜 |
跨語言開發 | 一般靠手寫或工具(OpenAPI 等) | 官方/社群產碼齊全,多語言一致 | 可由 XSD 開發,但體驗不一 |
前後相容與演進 | 靠文件與版本策略 | 欄位號、reserved、預設值策略清晰 | 命名空間與可選元素,但治理成本高 |
可讀性與除錯 | 高,易用 cURL/瀏覽器檢視 | 低,需工具解析 bytes | 高,但冗長 |
典型場景 | 公開 API、前端互動、後台工具 | 微服務內部通訊、gRPC、行動與 IoT | 企業整合、舊系統、配置、SOAP |
學習與生態 | 門檻低,生態廣 | 需理解 .proto 與工具鏈 | 歷史悠久,工具多但偏重 |
syntax = "proto3";
package demo.v1;
// 使用者資料
message User {
int64 id = 1; // 高頻欄位優先使用 1–15
string name = 2;
string email = 3;
repeated string roles = 4; // 多值欄位
}
// 訂單資料
message Order {
int64 id = 1;
int64 user_id = 2;
repeated Item items = 3;
Status status = 4;
int64 created_at_unix = 5; // 以 epoch 傳遞時間,避免時區陷阱
message Item {
int64 sku = 1;
int32 qty = 2;
}
enum Status {
STATUS_UNSPECIFIED = 0;
PLACED = 1;
PAID = 2;
SHIPPED = 3;
CANCELLED = 4;
}
}
// 若使用 gRPC,可直接定義服務
service OrderService {
rpc GetOrder(GetOrderRequest) returns (Order) {}
}
message GetOrderRequest { int64 id = 1; }
order = Order(
id=123,
user_id=42,
items=[Order.Item(sku=9001, qty=2)],
status=Order.Status.PAID,
created_at_unix=1726286400,
)
# 序列化為 bytes
payload = order.SerializeToString()
# 反序列化
obj = Order()
obj.ParseFromString(payload)
o := &demo_v1.Order{
Id: 123,
UserId: 42,
Items: []*demo_v1.Order_Item{
{Sku: 9001, Qty: 2},
},
Status: demo_v1.Order_PAID,
CreatedAtUnix: 1726286400,
}
// 序列化
b, err := proto.Marshal(o)
if err != nil {
// handle error
}
// 反序列化
var out demo_v1.Order
if err := proto.Unmarshal(b, &out); err != nil {
// handle error
}
Protobuf 以二進位、高效能與嚴格的結構定義,補足了 JSON 在效能與契約治理上的不足,如合理規劃欄位號與演進策略,可在維持相容性的前提下持續演進介面。
特別適合高併發與多語言的大型系統之間的高頻訊息收發場景。