Golang中JSON与Protocol Buffer的对比与选择

Golang中JSON与Protocol Buffer的对比与选择 我正在开发一个匹配引擎,希望我的服务能够接收订单消息,然后找到相应的匹配订单,接着将这些订单和匹配订单数组发送给其他微服务。我应该使用 JSON 还是协议缓冲区?

9 回复

好的,现在我明白了
多谢兄弟

更多关于Golang中JSON与Protocol Buffer的对比与选择的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


谢谢兄弟

我了解到协议缓冲区比JSON快6倍,而在我的应用场景中,延迟是一个重要考量因素。

那么在这种情况下你应该考虑使用 Protocol Buffers?我们无法替你做出决定。

如果你的应用程序使用 JSON 最终足够快,那就使用它。试试看!

如果你需要询问我们的意见,那么我认为你应该从 JSON 开始。上手要容易得多。
这实际上是一个设计问题,根据你目前提供的信息,没有理由选择 Protocol Buffers 而不是 JSON。

您可以考虑使用 JSON 序列 而非常规 JSON 对象。这种方式能让接收方基于流式处理进行解码,无需等待完整响应返回,有助于降低延迟。

先进行测量。Protobuf 虽然始终比 JSON 更紧凑,但并非自动比 JSON 更快。

我曾有一个程序需要处理大量数据,在文件间进行流式传输,并需要快速编码和解码。对于那个特定程序,protobuf 和 encoding/json 的性能相同,因此最终选择了 JSON 作为更优方案。

func main() {
    fmt.Println("hello world")
}

在开发匹配引擎时,选择 JSON 还是 Protocol Buffer(protobuf)取决于性能、可维护性和系统需求。以下是详细对比和示例代码,帮助您做出决策。

1. 性能对比

  • Protocol Buffer:序列化/反序列化速度快,数据体积小(二进制格式),适合高吞吐量场景。在匹配引擎中,订单消息频繁传输,protobuf 可减少延迟和带宽使用。
  • JSON:文本格式,可读性好,但序列化/反序列化较慢,数据体积较大。适用于调试或与外部系统交互。

示例代码:Protocol Buffer 实现订单消息

首先,定义 .proto 文件(如 order.proto):

syntax = "proto3";

message Order {
    string id = 1;
    string symbol = 2;
    double price = 3;
    int32 quantity = 4;
}

message MatchResult {
    repeated Order orders = 1;
    repeated Order matched_orders = 2;
}

使用 protoc 生成 Go 代码后,在 Go 中序列化/反序列化:

package main

import (
    "log"
    "github.com/golang/protobuf/proto"
    // 假设生成的包为 orderpb
)

func main() {
    // 创建订单消息
    order := &orderpb.Order{
        Id:       "12345",
        Symbol:   "BTCUSD",
        Price:    50000.0,
        Quantity: 100,
    }

    // 序列化为二进制
    data, err := proto.Marshal(order)
    if err != nil {
        log.Fatal("序列化错误:", err)
    }

    // 反序列化
    newOrder := &orderpb.Order{}
    err = proto.Unmarshal(data, newOrder)
    if err != nil {
        log.Fatal("反序列化错误:", err)
    }
    log.Printf("反序列化订单: %+v", newOrder)
}

示例代码:JSON 实现订单消息

package main

import (
    "encoding/json"
    "log"
)

type Order struct {
    ID       string  `json:"id"`
    Symbol   string  `json:"symbol"`
    Price    float64 `json:"price"`
    Quantity int     `json:"quantity"`
}

type MatchResult struct {
    Orders        []Order `json:"orders"`
    MatchedOrders []Order `json:"matched_orders"`
}

func main() {
    // 创建订单
    order := Order{
        ID:       "12345",
        Symbol:   "BTCUSD",
        Price:    50000.0,
        Quantity: 100,
    }

    // 序列化为 JSON
    data, err := json.Marshal(order)
    if err != nil {
        log.Fatal("JSON 序列化错误:", err)
    }

    // 反序列化
    var newOrder Order
    err = json.Unmarshal(data, &newOrder)
    if err != nil {
        log.Fatal("JSON 反序列化错误:", err)
    }
    log.Printf("反序列化订单: %+v", newOrder)
}

2. 可维护性和兼容性

  • Protocol Buffer:支持强类型和版本兼容(通过字段编号),适合长期演进的微服务架构。但需要预先定义 .proto 文件并生成代码。
  • JSON:灵活,无需预编译,但类型安全较弱,变更可能导致兼容性问题。

3. 选择建议

  • 如果您的匹配引擎要求低延迟、高吞吐量,且微服务间通信频繁,使用 Protocol Buffer
  • 如果需要快速原型开发、调试或与外部 RESTful API 交互,JSON 更合适。

在您的场景中,由于订单消息处理对性能敏感,建议优先选择 Protocol Buffer。

回到顶部