Protobuf簡介

1. 用途:編程

 把某種數據結構的信息,以某種格式保存起來。主要用於數據存儲、傳輸協議格式等場合。網絡

2. 優勢:數據結構

  a.性能好,效率高(時間和空間上比XML好,XML反序列化開銷大)socket

  b.代碼生成機制編程語言

eg:性能

    假設訂單包括以下屬性:ui

--------------------------------spa

    時間: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)只要增長一行讀取狀態的代碼。

  c.支持「向後兼容」和「向前兼容」

     「向後兼容」:當模塊B升級以後,它可以正確識別模塊A發出的老版本的協議。如上例中,因爲老版本沒有「狀態」這個屬性,在擴充協議時,能夠考慮把「狀態」屬性設置成爲非必填的,或者給「狀態」屬性設置一個缺省值。

    「向前兼容」:當模塊A升級之後,模塊B可以 正常識別模塊A發出的新版本的協議,這時新增長的「狀態」屬性會被忽略。

  d.支持多種編程語言(官方源代碼中包含了C++、Java、Python三種語言)

3. 缺點:

  a.應用不夠廣

  b.二進制格式致使可讀性差

  c.缺少自描述

相關文章
相關標籤/搜索