Protobuf協議概覽及開發指南
什么是protocol buffer
l 如何使其工作
l 與XML相比有哪些優勢?
l 聽起來像是不錯的解決方案,如何開始?
l 歷史原因
本文檔作為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 文件。
l 什么是protocol buffer
ProtocolBuffer是一種用于結構化數據串行化的靈活、高效、自動的方法,有如XML,不過它更小、更快、也更簡單。可以自定義數據結構,然后使用代碼生成器生成的代碼來讀寫這個數據結構。甚至可以在無需重新部署程序的情況下更新數據結構。
l 如何使其工作
首先需要在一個 .proto 文件中定義需要做串行化的數據結構信息。每個ProtocolBuffer信息是一小段邏輯記錄,包含一系列的鍵值對。如下有一個簡單的 .proto 文件定義了個人信息:
message Person { |
正如你所見,消息格式非常簡單,每個消息類型擁有一個或多個特定的數字字段,每個字段擁有一個名字和一個值類型。值類型可以是數字(整數或浮點)、布爾 型、字符串、原始字節或者其他ProtocolBuffer類型,還允許數據結構的分級。可以指定可選字段,必選字段和重復字段。可以在 http://code.google.com/apis/protocolbuffers/docs/proto.html到更多關于如何編 寫 .proto文件的信息。
在完成自定義消息報文后,就可以運行ProtocolBuffer編譯器,根據選定的語言類型將.proto 文件編譯 成特定語言的類。這些類提供了簡單的方法訪問每個字段(像是 query() 和 set_query() ),像是訪問類的方法一樣將結構串行化或反串行化。例如可以選擇C++語言,運行編譯如上的協議文件生成類叫做 Person 。隨后就可以在應用中使用 這個類來串行化的讀取報文信息。代碼示例如下:
Person person; |
而后,可以讀取報文中的數據,示例如下:
fstream input("myfile",ios::in | ios:binary); |
當然,你可以在不影響向后兼容的情況下任意給數據結構增加字段,舊有的數據會忽略新的字段。所以如果使用ProtocolBuffer作為通信協議,可以無須擔心破壞現有代碼的情況下進行協議擴展。
可以在API參考http://code.google.com/apis/protocolbuffers/docs/reference/overview.html中找到完整的參考,關于ProtocolBuffer的報文格式編碼則可以在http://code.google.com/apis/protocolbuffers/docs/encoding.html中找到。
l 與XML相比有哪些優勢?
ProtocolBuffer擁有比XML更高級的串行化結構數據的特性,ProtocolBuffer:
? 更簡單
? 小3-10倍
? 快20-100倍
? 更少的歧義
? 可以方便的生成數據存取類
例如,在XML中建模Person的name和email字段,代碼示例如下:
<person> |
ProtocolBuffer協議對應的報文如下:
#ProtocolBuffer的文本表示 |
當這個報文編碼到ProtocolBuffer的二進制格式http://code.google.com/apis /protocolbuffers/docs/encoding.html時只需要28字節和100-200ns的解析時間。而XML的版本需要69字節 (除去空白)和5000-10000ns的解析時間。
當然,操作ProtocolBuffer也很簡單,示例如下:
cout << "Name: " << person.name() << endl; |
而XML則需要,如下所示:
cout << "Name: " |
當然,ProtocolBuffer并不是在任何時候都比XML更合適,例如ProtocolBuffer無法對一個基 于標記文本的文檔建模,因為根本無法方便的在文本中插入結構。另外,XML是便于閱讀和編輯的,而ProtocolBuffer則不是。還有XML是自解 釋的,而ProtocolBuffer僅在擁有報文格式定義的 .proto 文件時才有意義。
l 聽起來像是不錯的解決方案,如何開始?
在地址http://code.google.com/p/protobuf/downloads/下載包,包含了Java、Python、C++的ProtocolBuffer編譯器,用于生成你需要的IO類。跟隨README的指令就可以做到構建和安裝編譯器。
安裝好之后,就可以跟著編程指導http://code.google.com/apis/protocolbuffers/docs/tutorials.html來選擇語言-隨后就是使用ProtocolBuffer創建一個簡單的應用了。
l 歷史原因
ProtocolBuffer最初是在Google開發的,用以解決索引服務器的請求、響應協議。在使用ProtocolBuffer之前,有一種格式用以處理請求和響應數據的編碼和解碼,并且支持多種版本的協議。而這最終導致了丑陋的代碼,有如:
if (version==3) { |
通信協議因此變得越來越復雜,因為開發者必須確保,發出請求的人和接受請求的人必須同時兼容,并且在一方開始使用新協議時,另外一方也要可以接受。
ProtocolBuffer設計用于解決這一類問題:
? 很方便引入新字段,而中間服務器可以忽略這些字段,直接傳遞過去而無需理解所有的字段。
? 格式可以自描述,并且可以在多種語言中使用(C++、Java等)。
然而用戶仍然需要手寫解析代碼。隨著系統的演化,他需要一些其他的功能:
? 自動生成編碼和解碼代碼,而無需自己編寫解析器。
? 除了用于簡短的RPC(Remote ProcedureCall)請求,人們使用ProtocolBuffer來做數據存儲格式(例如BitTable)。
? RPC服務器接口可以作為 .proto 文件來描述,而通過ProtocolBuffer的編譯器生成存根(stub)類供用戶實現服務器接口。
ProtocolBuffer現在已經是Google的混合語言數據標準了,現在已經正在使用的有超過48,162種報文格式定義和超過12,183個.proto 文件。他們已經將其成功應用于RPC系統和持續數據存儲系統。