protobuf和gRPC
protobuf 是一个平台无关,语言无关,可扩展的,用来序列化结构化数据的一个机制(想一下XML,但是更小,更快,更简单)。
gRPC是一个高性能的RPC框架,默认使用protobuf作为接口定义语言(IDL)和底层信息交换格式。可以让client像调用本地方法一样调用远程server,让创建分布式应用和服务更容易。gRPC的思想是:定义一个服务,指定可以被调用的方法,及方法的参数和返回。
gRPC可以轻松构建不同应用之间的通信
核心概念、架构和生命周期
-
定义服务,生成.proto文件。gRPC有四种service方法定义:
- 单项RPC,客户端发送一个消息,服务器接收一个消息。
rpc FindOne(FindOneRequest) returns(FindOneResponse);
- 服务端流式RPC,客户端发送一个请求到服务端,可获取一个数据流读取返回的消息。客户端从返回的数据流里一直读取知道没有更多消息为止。gRPC保证单个RPC调用中的消息顺序。
rpc List(ListRequest) returns(stream ListResponse);
- 客户端流式RPC,客户端使用写入流写入数据并发送一系列数据给服务端。一旦客户端完成了消息的写入,它就等待服务器读取消息并返回响应。同样,gRPC保证了单独RPC调用中的消息顺序。
rpc InsertMany(stream InsertManyRequest) returns(InsertManyResponse);
- 双向流RPC,两端分别拥有读写数据流发送数据和接收数据。两个数据了操作是互相独立的,客户端和服务器可以按照自己的方式任意顺序读写,每个消息流里的顺序会被保持.
rpc BidiList(stream BigListRequest) returns(stream BigListResponse);
- 单项RPC,客户端发送一个消息,服务器接收一个消息。
-
使用API
gRPC为protobuf提供了编译器插件,可以生成客户端和服务端端的代码,客户端调用API,服务端实现API。- 服务端实现服务接口,运行gRPC服务器处理客户端请求。gRPC底层解码请求,执行服务方法,编码请求返回。
- 客户端有一个stub,实现了服务端同样的方法。客户端可以在本地上调用这个方法,用适合的protobuf 消息类型封装参数——gRPC发送请求到服务器并接受服务器返回的protobuf响应。
-
同步vs异步
同步RPC调用会一直阻塞直到服务器结果返回,这是rpc最希望的抽象过程调用。另一方面,网络本身是异步的,在许多情况下,能够启动rpc而不阻塞当前线程是非常有用的。 -
RPC声明周期
- 单项RPC
- 客户端调用stub method,服务端会获得相关通知,这个通知包括客户端元数据、方法名、允许的响应期限(如果可以的话)
- 服务器可以直接发送自己的初始元数据(必须在任何响应之前发送),或者等待客户端的请求信息,具体哪个先发生,要看具体应用。
- 一旦服务器接收到客户端的请求信息,就会执行方法创建和组装对应的响应。如果成功的话,这个响应会包含状态码、可选的状态信息等状态信息和可选的跟踪信息等。
- 如果响应状态为OK,则客户端获得响应,将结束客户端的调用。
- 服务端流式RPC
服务端流式 RPC 除了在得到客户端请求信息后发送回一个应答流之外,与我们的简单例子一样。 - 客户端流式RPC
客户端流式 RPC 也基本与我们的简单例子一样,区别在于客户端通过发送一个请求流给服务端,取代了原先发送的单个请求。 - 双向流RPC
双向流式 RPC ,调用由客户端调用方法来初始化,而服务端则接收到客户端的元数据,方法名和截止时间。服务端可以选择发送回它的初始元数据或等待客户端发送请求。
下一步怎样发展取决于应用,因为客户端和服务端能在任意顺序上读写 - 这些流的操作是完全独立的。例如服务端可以一直等直到它接收到所有客户端的消息才写应答,或者服务端和客户端可以像"乒乓球"一样:服务端后得到一个请求就回送一个应答,接着客户端根据应答来发送另一个请求,以此类推。
- 单项RPC