简介
在http网络通讯时,一般使用Json或高效序列化类的方式对数据进行传输,高效序列化类比较流行的是谷歌的protocol buffer与spark的kryo。下面介绍一下protocol buffer,当对数据的描述由使用JSON改为Protobuf,这样就可通过IDL实现强制约束,包括数据类型、字段命名等,相比json格式protocol字段格式相对固定。
优点
protobuf 不管是处理时间上,还是空间占用上都优于现有的其他序列化方式。内存暂用是java 序列化的1/9,时间也是差了一个数量级,一次操作在1us左右。
缺点
缺点:就是对象结构体有限制,只适合于内部系统使用。
Mac安装Protobuf编译Java
-
安装Homebrew(如果已有编译环境这步可忽略)
Homebrew是一个类yum的软件包管理器,需要使用homebrew安装protobuf所需的编译器gcc等软件。
Homebrew安装方法:https://jingyan.baidu.com/article/fec7a1e5ec30341190b4e7e5.html 安装Homebrew
ruby -e "$(curl --insecure -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
注意:安装HomeBrew时会报
...could not lock config file .git/config: Permission denied
,所以先修改文件权限sudo chgrp -R admin /usr/local sudo chmod -R g+w /usr/local
安装编译环境
brew install gcc
-
在Mac上安装protobuf
protobuf下载地址 https://github.com/google/protobuf/tags?after=v3.0.0-alpha-1
解压压缩包
tar zxvf protobuf-2.5.0.tar.gz
cd到protobuf-2.5.0 目录
cd protobuf-2.5.0
指定安装目录(/Users/gongenbo/Tools/protobuf安装目录)
./configure --prefix=/Users/gongenbo/Tools/protobuf
安装
make make install
设置环境变量
sudo vi /etc/profile
export PROTOBUF=/opt/tools/protobuf-2.5.0 export PATH=$JAVA_HOME/bin:$PROTOBUF/bin:$PATH
刷新环境变量
source /etc/profile
测试protobuf
protoc --version
-
编写.proto文件,可以自己写,也可以复制example中的文件过来
protobuf.proto
option java_package = "com.example.demo"; option java_outer_classname = "PersonPb"; message Person { required string name = 1; required int32 id = 2; optional string email = 3; enum PhoneType { MOBILE = 0; HOME = 1; WORKE = 2; } message PhoneNumber { required string number = 1; optional PhoneType type = 2 [default = HOME]; } repeated PhoneNumber phone = 4; message CountryInfo { required string name = 1; required string code = 2; optional int32 number = 3; } } message AddressBook { repeated Person person = 1; }
-
编译生成Java
protoc -I=src/main/resource/proto --java_out=src/main/java src/main/resource/proto/protobuf.proto
PersonPb.java
private PersonPb() {} public static void registerAllExtensions( com.google.protobuf.ExtensionRegistry registry) { } public interface PersonOrBuilder extends com.google.protobuf.MessageOrBuilder { // required string name = 1; /** * <code>required string name = 1;</code> */ boolean hasName(); ... ...内容很多,(稍后附件中有) ... com.google.protobuf.Descriptors.FileDescriptor .internalBuildGeneratedFileFrom(descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] { }, assigner); } // @@protoc_insertion_point(outer_class_scope) }
-
使用:
public class MainTest { public static void main(String[] args) { System.out.println("Test_Systemout"); PersonPb.AddressBook.Builder build = PersonPb.AddressBook.newBuilder(); PersonPb.Person person1 = PersonPb.Person.newBuilder().setId(1).setName("xxxxxxi").setEmail("123@qq.com"). addPhone(PersonPb.Person.PhoneNumber.newBuilder().setNumber("15211112222").setType(PersonPb.Person. PhoneType.HOME).build()).build(); build.addPerson(person1); PersonPb.Person person2 = PersonPb.Person.newBuilder().setId(2).setName("sasasasas").setEmail("qqqqq@qq.com"). addPhone(PersonPb.Person.PhoneNumber.newBuilder().setNumber("15211112222").setType(PersonPb.Person. PhoneType.HOME).build()).build(); build.addPerson(person2); for (int i = 0; i < build.getPersonList().size(); i++) { System.out.println("name=" + build.getPersonList().get(i).getName()); } } }
核心概念
1,.proto文件5/10/2017 10:44:16 PM 相当于确定数据协议,数据结构中存在哪些数据,数据类型是怎么样
2,modifiers
- 2.1. required 不可以增加或删除的字段,必须初始化
- 2.2 optional 可选字段,可删除,可以不初始化
- 2.3 repeated 可重复字段, 对应到java文件里,生成的是List
3,Message 在proto文件里,数据的协议时以Message的形式表现的。
4, Build 生成具体的java类时,例如Person.java,同时会存在build方法。文档的意思是对于转化后的数据,具有唯一性,build提供了便利的方法来初始化这些数据。
参考
win7如何安装maven、安装protoc: http://www.aboutyun.com/thread-8212-1-1.html
Mac安装Protobuf编译Java: http://blog.csdn.net/u013045971/article/details/50592998
您的打赏是对我最大的鼓励!