protobuf学习(1):初识protobuf

概述

由于学习Netty过程中需要结合protobuf,”不得已“拓展学习一下。

protobuf是什么

protobuf是google protocol buffers的简称,是google早年推出的一个RPC框架。简单的来讲,protobuf可以看作一种协议,他可以更好的、体积更小的对数据进行“编码”和“解码”,实质上就是序列化和反序列化的过程。与之后google推出的gRPC以及Facebook开源的Thrift属于同一种领域的技术。ProtoBuf 是一种数据表达方式,根据 G 家自己的描述,应该叫做数据交换格式,注意这里使用的是 交换 字眼,也就是说着重于在数据的传输上。

RPC库的使用原理

提到RPC,不得不提到在一种技术——RMI(remote method invocation),顾名思义远程方法调用,支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用,说人话就是支持不同机器上无感知的远程调用。JAVA RMI支持不同虚拟机之间的通信,这些虚拟机可以在不同的主机上、也可以在同一个主机上;一个虚拟机中的对象调用另一个虚拟上中的对象的方法,只不过是允许被远程调用的对象要通过一些标志加以标识。使用起来就是A机器上程序调用了一个方法x(),实际上x()方法是B机器程序中的一个方法,但是A机器上调用起来就像调用本程序中的某个本地方法一样”无感知“,既然是跨机器调用,本质上是A机器上把需要调用方法描述、参数等元素序列化成字节码的形式,传递到B机器上,B机器将接收到的字节码还原成源方法调用描述执行,并且返回结果给A机器。这种形式的远程调用存在一个限制,就是A、B机器必须都是Java代码,存在语言限制,优点在于,这种调用形式实现是对开发者屏蔽的,也就是说开发者只需要关心怎么使用这种技术,并不需要关系怎么实现,但是在这个远程调用过程中,一定是存在代码生成这一动作,在调用端被成为:stub,在服务端被称为:skeleton,当调用发生的时候,调用端把”调用描述“序列化之后,通过socket传递给被调用者,被调用者把数据反序列化之后变成可以理解的方法调用并执行,之后将结果在序列化之后返回给调用者。所以从调用过程中可以看出,序列化和反序列化是RMI调用的重要组成部分

 

前面说了这么多RMI其实是为了更好的理解RPC(remote procedure call)远程过程调用,原理和RMI很相似。

  • RPC相对于RMI的优点——跨语言,调用端和服务端可以是不同的语言写的,调用端可以是java,服务端可以是python。
  • 很多RPC框架的编写模式也都是类似的,如下:
  1. 定义一个接口说明文件(调用描述),描述了对象(结构体)、对象成员、接口等一系列信息,这个说明文件是独立于语言的,是一个文本文件
  2. 通过RPC框架提供的编译器,通过接口说明文件编译成具体具体语言文件,比如你想在客户端生成java语言,在服务端生成C语言,它就可以通过一些参数设置帮你完成
  3. 在客户端和服务端分别引入RPC编译器生成的编译文件即可在客户端像调用本地方法一样调用远程服务端

由上述过程可以看出RPC的使用过程有点类似于webservice,却别在:

  1. 于编码和解码的效率(序列化和反序列化),webservice的xml描述文件数据传输太大
  2. webservice通过http传输数据,RPC通过socket,效率上肯定是socket方式高

特别是在及时传输效率要求高的大规模系统中,RPC的优势不言而喻,分布式和微服务的形式中后端存在大量的调用,体现的更为明显。

protobuf基本了解

官网https://developers.google.com/protocol-buffers

protobuf学习(1):初识protobuf_第1张图片

protocol buffers是一种语言中立、平台中立的可扩展机制,用于序列化结构化数据

看到主页的三段代码,第一段就属于接口说明,对于接口说明的数据类型来说,RPC框架支持的语言越多,其数据类型就越少,因为RPC框架支持的数据类型是其支持的所有语言数据类型的交集。每一个字段后面的1、2、3并不是指的是字段的值,而是代表字段的顺序,也可以说是一种标识。

通过第二段代码(另一种语言)将接口说明的对象写入到输出流中。

第三段代码(C语言)将接收流中的数据并反序列化为自己可读数据

你可能感兴趣的:(#,Google,Protocol,Buffers,protobuf,google,rpc,netty,java)