protobuf详解

      protobuf是由google开发的一种数据交换格式。使用protobuf可以很轻松的实现消息的序列化与反序列化。序列化时,根据.proto文件将数据解析成二进制流用于传输;反序列化时,再根据.proto文件将二进制流解析成所需要的数据。它可以作为RabbitMQ的Message数据格式进行传输,由于是结构化的数据,这样就极大地方便了Consumer的数据高效处理。

附上一张RabbitMQ的结构图,在ClientA、ClientB、Client1、Client2、Client3端分别使用protobuf用于数据的序列化与反序列化。

关于RabbitMQ的详细介绍,欢迎查看我的上篇博文 RabbitMQ基础知识详解

优点:

1、性能好、效率高

2、代码生成机制

比如有个电子商务的系统(假设用C++实现),采用上图的RabbitMQ架构,其中的ClientA、B需要发送大量的订单信息给Client1、2、3,通讯的方式使用socket。
假设订单包括如下属性:
--------------------------------
  时间:time(用整数表示)
  客户id:userid(用整数表示)
  交易金额:price(用浮点数表示)
  交易的描述:desc(用字符串表示)
--------------------------------
  如果使用protobuf实现,首先要写一个proto文件(不妨叫Order.proto),在该文件中添加一个名为"Order"的message结构,用来描述通讯协议中的结构化数据。该文件的内容大致如下:

--------------------------------

message Order
{
  required int32 time = 1;
  required int32 userid = 2;
  required float price = 3;
  optional string desc = 4;
}

--------------------------------
  然后,使用protobuf内置的编译器编译该proto文件。由于本例子的模块是C++,你可以通过protobuf编译器的命令行参数,让它生成C++语言的“订单包装类”。(一般来说,一个message结构会生成一个包装类)
  然后你使用类似下面的代码来序列化/解析该订单包装类:
--------------------------------

// 发送方

Order order;
order.set_time(XXXX);
order.set_userid(123);
order.set_price(100.0f);
order.set_desc("a test order");

string sOrder;
order.SerailzeToString(&sOrder);

// 然后调用某种socket的通讯库把序列化之后的字符串发送出去
// ......

--------------------------------

// 接收方

string sOrder;
// 先通过网络通讯库接收到数据,存放到某字符串sOrder
// ......

Order order;
if(order.ParseFromString(sOrder))  // 解析该字符串
{
  cout << "userid:" << order.userid() << endl
          << "desc:" << order.desc() << endl;
}
else
{
  cerr << "parse error!" << endl;
}

--------------------------------

      有了这种代码生成机制,开发人员就不用吭哧吭哧地编写那些协议解析的代码了。
      万一将来需求发生变更,要求给订单再增加一个“状态”的属性,那只需要在Order.proto文件中增加一行代码。对于发送方(模块A),只要增加一行设置状态的代码;对于接收方(模块B)只要增加一行读取状态的代码。
  另外,如果通讯双方使用不同的编程语言来实现,使用这种机制可以有效确保两边的模块对于协议的处理是一致的。

3、支持“向后兼容”和所谓的“向后兼容”

      “向后兼容“:当ClientA、B没有改变,而Client1、2、3给订单增加了一个“状态”的属性时,它能够正确识别接受到的数据。由于ClientA、B端没有“状态”这个属性,在扩充协议时,可以考虑把“状态”属性设置成非必填 的,或者给“状态”属性设置一个缺省值。
   “向前兼容”:当ClientA、B给订单增加了一个“状态”的属性,而Client1、2、3没有改变时,它能够正确识别接受到的数据。这时候,新增加的“状态”属性会被忽略。
   “向后兼容”和“向前兼容”有什么作用呢?

     举个例子:当你维护一个很庞大的分布式系统时,由于你无法同时升级所有模块,为了保证在升级过程中,整个系统能够尽可能不受影响,就需要尽量保证通讯协议的“向后兼容”或“向前兼容”。

4,支持多种编程语言(java,c++,python)

缺点:

1、应用不够广

2、二进制格式导致可读性差

3、缺乏自描述

本文部分转载自http://blog.csdn.net/caisini_vc/article/details/5599468

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值