分布式通讯-序列化之protobuf

来源:互联网 发布:c语言源程序的扩展名 编辑:程序博客网 时间:2024/06/06 03:08

Protobuf是一个高性能、易扩展的序列化框架,它的性能测试有关数据可以参看官方文档。通常在TCP Socket通讯(RPC调用)相关的应用中使用;它本身非常简单,易于开发,而且结合Netty框架可以非常便捷的实现一个RPC应用程序,同时Netty也为Protobuf解决了有关Socket通讯中“半包、粘包”等问题(反序列化时,字节成帧)。


1. 安装protobuf
windows环境从https://github.com/google/protobuf/releases/tag/v3.3.0下载 protoc-3.3.0-win32.zip并解压。
2. 创建.proto文件
Protobuf需要一个schema声明文件,后缀为“.proto”的文本文件,内容样例如下:

option java_package ="cn.creditease.protobuf";option java_outer_classname="PersonProtos";message Person{    required string name=1;    required int32 age=2;    optional string email=3 [default="test@163.com"] ;//optional 可以为空    repeated string childs = 4 ;//[packed=true] /repeated表示这个字段的值可以允许被重复多次,对应java List<String> childs,packed=true表示压缩,但是只能压缩int32等基本类型    map<string, Account> bankaccount = 5;  }message Account{    required string accId=1;    required string accName=2;    required double balance=3;}

3. 生成java文件

D:\protoc-3.3.0-win32\bin>protoc --java_out=./ Person.proto

通过“–java_out”指定生成JAVA代码保存的目录,后面紧跟“.proto”文件的路径。此后我们看到生成 了Package和一个PersonProtos.java文件,我们只需要把此java文件复制到项目中即可。
4. 测试类

public class ProtobufDemo {    public static void main(String[] args) throws IOException {        PersonProtos.Person.Builder personBuilder=PersonProtos.Person.newBuilder();        personBuilder.setAge(10);        personBuilder.setName("zhagnsan");        //对应proto文件repeated string childs = 4 ;        personBuilder.addChilds("张小三");        personBuilder.addChilds("张小小三");        //map<string, Account> bankaccount = 5;        PersonProtos.Account.Builder accountBuilder= PersonProtos.Account.newBuilder();        accountBuilder.setAccId("898989898989");        accountBuilder.setAccName("张三");        accountBuilder.setBalance(2999.09);        personBuilder.putBankaccount("ICBC",accountBuilder.build());        accountBuilder.setAccId("4556689898989");        accountBuilder.setAccName("张三");        accountBuilder.setBalance(1900000);        personBuilder.putBankaccount("CMBC",accountBuilder.build());        PersonProtos.Person person=personBuilder.build();        //第一种用法        byte[] data=person.toByteArray();        System.out.println(data.length);        //第二种用法        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();        //生成一个由:[字节长度][字节数据]组成的package。特别适合RPC场景        person.writeDelimitedTo(outputStream);        ByteArrayInputStream inputStream=new ByteArrayInputStream(outputStream.toByteArray());        PersonProtos.Person result=PersonProtos.Person.parseDelimitedFrom(inputStream);        System.out.println(result.toString());    }
原创粉丝点击