社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
上一篇文章介绍的是nginx做为负载均衡与后端grpc的集成,没有继续深入下去,因为这个需要线上真正实践才会有更多的感悟,之后入职后有体会的话再继续写吧。
刚好我也比较好奇protobuf到底和grpc是个什么关系,protobuf在整个rpc的过程中起的是什么作用,所以我之后的几篇文章都会是关于protobuf的。
我还是从网上找了几个网上的资料,看看前人的研究成果:
proto3官网 毫不犹豫推荐官网的文章
Google Protocol Buffer 的使用和原理 这个文章有点老,介绍的不是proto3,但是作者研究的挺深入的。
proto3语言指南 这个有点像官网英文的翻译和作者自己的总结,也非常不错
摘抄一段别人的描述:Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。它很适合做数据存储或 RPC 数据交换格式。可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。看到这个描述第一感觉是云里雾里,研究后总结protobuf的以下几点:
message Person {
string name = 1;
int32 id = 2;
string email = 3;
}
与前面介绍grpc使用的步骤一样,现在准备一个.proto文件
syntax = "proto3"; package tutorial; option java_package = "com.example.tutorial"; 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; }
使用前面文章介绍的maven plugin生成代码。
将生成好的代码AddressBookProtos.java拷贝到你新建的工程,类似如下结构:
参考官网的说明,新建一个WriteObject.java, 代码如下,通过输入逐渐构造Person对象,并写入一个文件,记得在启动参数里加上文件的路径
static Person PromptForAddress(BufferedReader stdin, PrintStream stdout) throws IOException { Person.Builder person = 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; } Person.PhoneNumber.Builder phoneNumber = 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(Person.PhoneType.MOBILE); } else if (type.equals("home")) { phoneNumber.setType(Person.PhoneType.HOME); } else if (type.equals("work")) { phoneNumber.setType(Person.PhoneType.WORK); } else { stdout.println("Unknown phone type. Using default."); } person.addPhones(phoneNumber); } return person.build(); } public static void main(String[] args) throws IOException { if (args.length != 1) { System.err.println("Usage: AddPerson ADDRESS_BOOK_FILE"); System.exit(-1); } AddressBook.Builder addressBook = AddressBook.newBuilder(); // Read the existing address book. try { addressBook.mergeFrom(CodedInputStream.newInstance(new FileInputStream(args[0]))); } catch (FileNotFoundException e) { System.out.println(args[0] + ": File not found. Creating a new file."); } // Add an address. addressBook.addPeople( PromptForAddress(new BufferedReader(new InputStreamReader(System.in)), System.out)); // Write the new address book back to disk. FileOutputStream output = new FileOutputStream(args[0]); addressBook.build().writeTo(output); output.close(); }
运行后用sublime打开写入的文件如下, 具体为什么是这种后面我会具体研究,现在所要知道的是这种序列化的方式肯定比一般的xml和json要节省空间的
参考官网新建ReadObject.java, 代码如下, 读取同样的文件,反序列化后就能取出对应的字段值
static void Print(AddressBook addressBook) { for (Person person: addressBook.getPeopleList()) { System.out.println("Person ID: " + person.getId()); System.out.println(" Name: " + person.getName()); for (Person.PhoneNumber phoneNumber : person.getPhonesList()) { switch (phoneNumber.getType()) { case MOBILE: System.out.print(" Mobile phone #: "); break; case HOME: System.out.print(" Home phone #: "); break; case WORK: System.out.print(" Work phone #: "); break; } System.out.println(phoneNumber.getNumber()); } } } public static void main(String[] args) throws IOException { if (args.length != 1) { System.err.println("Usage: ListPeople ADDRESS_BOOK_FILE"); System.exit(-1); } // Read the existing address book. AddressBook addressBook = AddressBook.parseFrom(new FileInputStream(args[0])); Print(addressBook); }
运行一下结果如下:
Person ID: 1
Name: zack
至此,大概了解了一下怎么单独使用protobuf以及它在grpc中的作用,后面我会继续研究protobuf3的语法细节和序列化细节
另附文章中提到的工程文件:
欢迎关注我的个人的博客www.zhijianliu.cn, 虚心求教,有错误还请指正轻拍,谢谢
版权声明:本文出自志健的原创文章,未经博主允许不得转载
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!