Protocol Buffers简明教程
隨著微服務架構的流行,RPC框架漸漸地成為服務框架的一個重要部分。在很多RPC的設計中,都采用了高性能的編解碼技術,Protocol Buffers就屬于其中的佼佼者。Protocol Buffers是Google開源的一個語言無關、平臺無關的通信協議,其小巧、高效和友好的兼容性設計,使其被廣泛使用。
概述
protobuf是什么?
Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.
- Google良心企業出廠的;
- 是一種序列化對象框架(或者說是編解碼框架),其他功能相似的有Java自帶的序列化、Facebook的Thrift和JBoss Marshalling等;
- 通過proto文件定義結構化數據,其他功能相似的比如XML、JSON等;
- 自帶代碼生成器,支持多種語言;
核心特點
- 語言無關、平臺無關
- 簡潔
- 高性能
- 良好的兼容性
為什么叫“Protocol Buffers”?
官方如是說:
The name originates from the early days of the format, before we had the protocol buffer compiler to generate classes for us. At the time, there was a class called ProtocolBuffer which actually acted as a buffer for an individual method. Users would add tag/value pairs to this buffer individually by calling methods like AddValue(tag, value). The raw bytes were stored in a buffer which could then be written out once the message had been constructed.
Since that time, the “buffers” part of the name has lost its meaning, but it is still the name we use. Today, people usually use the term “protocol message” to refer to a message in an abstract sense, “protocol buffer” to refer to a serialized copy of a message, and “protocol message object” to refer to an in-memory object representing the parsed message.
“變態的”性能表現
有位網友曾經做過各種通用序列化協議技術的對比,我這里直接拿來給大家感受一下:
序列化響應時間對比
序列化bytes對比
具體的數字
快速開始
以下示例源碼已上傳至github:ginobefun/learning_projects
新建一個maven項目并添加依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.ginobefunny.learning</groupId> <artifactId>leanring-protobuf</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.2.0</version> </dependency> </dependencies> </project> 新建protobuf的消息定義文件addressbook.proto
syntax = "proto3"; // 聲明為protobuf 3定義文件 package tutorial; option java_package = "com.ginobefunny.learning.protobuf.message"; // 聲明生成消息類的java包路徑 option java_outer_classname = "AddressBookProtos"; // 聲明生成消息類的類名 message Person { string name = 1; int32 id = 2; string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORK = 2; } message PhoneNumber { string number = 1; PhoneType type = 2; } repeated PhoneNumber phones = 4; } message AddressBook { repeated Person people = 1; } 使用protoc工具生成消息對應的Java類
- 從已發布版本中下載protoc工具,比如protoc-3.2.0-win32;
- 解壓后將bin目錄添加到path路徑;
- 執行以下protoc命令生成Java類:
protoc -I=. --java_out=src/main/java addressbook.proto
編寫測試類寫入和讀取序列化文件
- AddPerson類通過用戶每次添加一個聯系人,并序列化保存到指定文件中。
public class AddPerson {// 通過用戶輸入構建一個Person對象 static AddressBookProtos.Person promptForAddress(BufferedReader stdin, PrintStream stdout) throws IOException { AddressBookProtos.Person.Builder person = AddressBookProtos.Person.newBuilder(); stdout.print("Enter person ID: "); person.setId(Integer.valueOf(stdin.readLine())); stdout.print("Enter name: "); person.setName(stdin.readLine()); stdout.print("Enter email address (blank for none): "); String email = stdin.readLine(); if (email.length() > 0) { person.setEmail(email); } while (true) { stdout.print("Enter a phone number (or leave blank to finish): "); String number = stdin.readLine(); if (number.length() == 0) { break; } AddressBookProtos.Person.PhoneNumber.Builder phoneNumber = AddressBookProtos.Person.PhoneNumber.newBuilder().setNumber(number); stdout.print("Is this a mobile, home, or work phone? "); String type = stdin.readLine(); if (type.equals("mobile")) { phoneNumber.setType(AddressBookProtos.Person.PhoneType.MOBILE); } else if (type.equals("home")) { phoneNumber.setType(AddressBookProtos.Person.PhoneType.HOME); } else if (type.equals("work")) { phoneNumber.setType(AddressBookProtos.Person.PhoneType.WORK); } else { stdout.println("Unknown phone type. Using default."); } person.addPhones(phoneNumber); } return
轉載于:https://www.cnblogs.com/GarfieldEr007/p/10113332.html
總結
以上是生活随笔為你收集整理的Protocol Buffers简明教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿昔洛韦多少钱啊?
- 下一篇: C语言结构体篇 结构体