Protobuf協議概覽及開發指南

jopen 12年前發布 | 2K 次閱讀 Windows

  什么是protocol buffer

如何使其工作

與XML相比有哪些優勢?

聽起來像是不錯的解決方案,如何開始?

歷史原因

本文檔作為protocol buffer的開發者指南,它是一種語言無關、跨平臺、擴展性良好的用于通信、數據存儲的結構化數據串行化方法。

本文檔的讀者是希望使用protocol buffer的Java、C++或Python開發者。這個概覽簡要介紹了protocol buffer,并告訴你如何開始。當然你可以參考以下的編程指導深入了解protocolbuffer編碼方式 http://code.google.com/apis/protocolbuffers/docs/encoding.html。

API參考文檔http://code.google.com/apis/protocolbuffers/docs/reference/overview.html同樣也是提供了這三種編程語言的版本。

不同協議語言http://code.google.com/apis/protocolbuffers/docs/proto.html和樣式http://code.google.com/apis/protocolbuffers/docs/style.html用于指導如何更規范的編寫 .proto 文件。

什么是protocol buffer

ProtocolBuffer是一種用于結構化數據串行化的靈活、高效、自動的方法,有如XML,不過它更小、更快、也更簡單。可以自定義數據結構,然后使用代碼生成器生成的代碼來讀寫這個數據結構。甚至可以在無需重新部署程序的情況下更新數據結構。

如何使其工作

首先需要在一個 .proto 文件中定義需要做串行化的數據結構信息。每個ProtocolBuffer信息是一小段邏輯記錄,包含一系列的鍵值對。如下有一個簡單的 .proto 文件定義了個人信息:

message Person {
    required string name=1;
    required int32 id=2;
    optional string email=3;

    enum PhoneType {
        MOBILE=0;
        HOME=1;
        WORK=2;
    }

    message PhoneNumber {
        required string number=1;
        optional PhoneType type=2 [default=HOME];
    }

    repeated PhoneNumber phone=4;
}

    正如你所見,消息格式非常簡單,每個消息類型擁有一個或多個特定的數字字段,每個字段擁有一個名字和一個值類型。值類型可以是數字(整數或浮點)、布爾 型、字符串、原始字節或者其他ProtocolBuffer類型,還允許數據結構的分級。可以指定可選字段,必選字段和重復字段。可以在 http://code.google.com/apis/protocolbuffers/docs/proto.html到更多關于如何編 寫 .proto文件的信息。

在完成自定義消息報文后,就可以運行ProtocolBuffer編譯器,根據選定的語言類型將.proto 文件編譯 成特定語言的類。這些類提供了簡單的方法訪問每個字段(像是 query() 和 set_query() ),像是訪問類的方法一樣將結構串行化或反串行化。例如可以選擇C++語言,運行編譯如上的協議文件生成類叫做 Person 。隨后就可以在應用中使用 這個類來串行化的讀取報文信息。代碼示例如下:

Person person;
person.set_name("John Doe");
person.set_id(1234);
person.set_email("jdoe@example.com");
fstream.output("myfile",ios::out | ios::binary);
person.SerializeToOstream(&output);

而后,可以讀取報文中的數據,示例如下:

fstream input("myfile",ios::in | ios:binary);
Person person;
person.ParseFromIstream(&input);
cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

當然,你可以在不影響向后兼容的情況下任意給數據結構增加字段,舊有的數據會忽略新的字段。所以如果使用ProtocolBuffer作為通信協議,可以無須擔心破壞現有代碼的情況下進行協議擴展。

可以在API參考http://code.google.com/apis/protocolbuffers/docs/reference/overview.html中找到完整的參考,關于ProtocolBuffer的報文格式編碼則可以在http://code.google.com/apis/protocolbuffers/docs/encoding.html中找到。

與XML相比有哪些優勢?

ProtocolBuffer擁有比XML更高級的串行化結構數據的特性,ProtocolBuffer:

?  更簡單

?  小3-10倍

?  快20-100倍

?  更少的歧義

?  可以方便的生成數據存取類

例如,在XML中建模Person的name和email字段,代碼示例如下:

<person>
    <name>John Doe</name>
    <email>jdoe@example.com</email>
</person>

ProtocolBuffer協議對應的報文如下:

#ProtocolBuffer的文本表示
#這不是正常時使用的二進制數據
person {
    name: "John Doe"
    email: "jdoe@example.com"
}

當這個報文編碼到ProtocolBuffer的二進制格式http://code.google.com/apis /protocolbuffers/docs/encoding.html時只需要28字節和100-200ns的解析時間。而XML的版本需要69字節 (除去空白)和5000-10000ns的解析時間。

當然,操作ProtocolBuffer也很簡單,示例如下:

cout << "Name: " << person.name() << endl;
cout << "E-mail: " << person.email() << endl;

而XML則需要,如下所示:

cout << "Name: "
     << person.getElementsByTagName("name")->item(0)->innerText()
     << endl;
cout << "E-mail: "
     << person.getElementsByTagName("email")->item(0)->innerText()
     << end;

當然,ProtocolBuffer并不是在任何時候都比XML更合適,例如ProtocolBuffer無法對一個基 于標記文本的文檔建模,因為根本無法方便的在文本中插入結構。另外,XML是便于閱讀和編輯的,而ProtocolBuffer則不是。還有XML是自解 釋的,而ProtocolBuffer僅在擁有報文格式定義的 .proto 文件時才有意義。

聽起來像是不錯的解決方案,如何開始?

在地址http://code.google.com/p/protobuf/downloads/下載包,包含了Java、Python、C++的ProtocolBuffer編譯器,用于生成你需要的IO類。跟隨README的指令就可以做到構建和安裝編譯器。

安裝好之后,就可以跟著編程指導http://code.google.com/apis/protocolbuffers/docs/tutorials.html來選擇語言-隨后就是使用ProtocolBuffer創建一個簡單的應用了。

歷史原因

ProtocolBuffer最初是在Google開發的,用以解決索引服務器的請求、響應協議。在使用ProtocolBuffer之前,有一種格式用以處理請求和響應數據的編碼和解碼,并且支持多種版本的協議。而這最終導致了丑陋的代碼,有如:

if (version==3) {
    ...
}else if (version>4) {
    if (version==5) {
        ...
    }
    ...
}

通信協議因此變得越來越復雜,因為開發者必須確保,發出請求的人和接受請求的人必須同時兼容,并且在一方開始使用新協議時,另外一方也要可以接受。

ProtocolBuffer設計用于解決這一類問題:

?  很方便引入新字段,而中間服務器可以忽略這些字段,直接傳遞過去而無需理解所有的字段。

?  格式可以自描述,并且可以在多種語言中使用(C++、Java等)。

然而用戶仍然需要手寫解析代碼。隨著系統的演化,他需要一些其他的功能:

?  自動生成編碼和解碼代碼,而無需自己編寫解析器。

?  除了用于簡短的RPC(Remote ProcedureCall)請求,人們使用ProtocolBuffer來做數據存儲格式(例如BitTable)。

?  RPC服務器接口可以作為 .proto 文件來描述,而通過ProtocolBuffer的編譯器生成存根(stub)類供用戶實現服務器接口。

ProtocolBuffer現在已經是Google的混合語言數據標準了,現在已經正在使用的有超過48,162種報文格式定義和超過12,183個.proto 文件。他們已經將其成功應用于RPC系統和持續數據存儲系統。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!