官方文档-What is gRPC?

·  阅读 239

官方原版:www.grpc.io/docs/ 中文翻译版:doc.oschina.net/grpc?t=5683…

Introduction to gRPC

Overview

在 gRPC 中,客户端应用程序可以直接调用不同机器上的服务器应用程序上的方法,就像它是本地对象一样,使您可以更轻松地创建分布式应用程序和服务。在服务器端,服务器实现了这个接口并运行一个 gRPC 服务器来处理客户端调用。 在客户端,客户端有一个stub存根(在某些语言中简称为客户端),它提供与服务器相同的方法。

image.png

Working with Protocol Buffers

默认情况下,gRPC 使用 Protocol Buffers,这是 Google 用于序列化结构化数据的成熟开源机制(尽管它可以与其他数据格式一起使用,例如 JSON)。

使用Protocol Buffers的第一步是要在proto文件中定义序列化的数据的结构:这是一个带有.proto 扩展名的普通文本文件。Protocol Buffers数据被构造为message,其中每条message都是一个小的逻辑信息记录,包含一系列称为字段的键-值对。 这是一个简单的例子:

message Person {
  string name = 1;
  int32 id = 2;
  bool has_ponycopter = 3;
}
复制代码

然后,一旦你指定了你的数据结构,你就可以使用Protocol Buffers编译器protoc从你的proto定义中以你喜欢的语言生成数据访问类。它们为每个字段提供简单的访问器,如 name() 和 set_name(),以及将整个结构序列化/解析为原始字节/从原始字节序列化/解析整个结构的方法。例如选择的语言是C++,则在上面的示例上运行编译器将生成一个名为Person的类。 然后,可以在应用程序中使用此类来填充、序列化和检索Person message。

您可以在普通的proto文件中定义gRPC服务,并将RPC方法参数和返回类型指定为协议缓冲区消息:

// The greeter service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the user's name.
message HelloRequest {
  string name = 1;
}

// The response message containing the greetings
message HelloReply {
  string message = 1;
}
复制代码

gRPC使用特殊gRPC插件的protoc从您的proto文件生成代码:您将获得生成的gRPC客户端和服务器代码,以及用于填充、序列化和检索message的代码。

Protocol buffer versions

虽然可以使用 Proto2(当前默认的protocol buffers版本),但建议将Proto3与gRPC一起使用,

Core concepts, architecture and lifecycle

Overview

Service definition

与许多 RPC 系统一样,gRPC 基于定义服务的思想,指定可以通过参数和返回类型远程调用的方法。 默认情况下,gRPC 使用协议缓冲区作为接口定义语言(IDL)来描述服务接口和有效负载消息的结构。 如果需要,可以使用其他替代方案。

service HelloService {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string greeting = 1;
}

message HelloResponse {
  string reply = 1;
}
复制代码

gRPC 允许您定义四种服务方法:

  • 一元 RPC,客户端向服务器发送单个请求并返回单个响应,就像普通的函数调用一样。
rpc SayHello(HelloRequest) returns (HelloResponse);
复制代码
  • 服务器流式 RPC,客户端向服务器发送请求并获取流以读取一系列消息。 客户端从返回的流中读取,直到没有更多消息。 gRPC 保证单个 RPC 调用中的消息排序。
rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);
复制代码
  • 客户端流式 RPC,其中客户端写入一系列消息并将它们发送到服务器,再次使用提供的流。 一旦客户端完成写入消息,它等待服务器读取它们并返回其响应。 gRPC 再次保证单个 RPC 调用中的消息排序。
rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);
复制代码
  • 双向流式 RPC,其中双方使用读写流发送一系列消息。 这两个流独立运行,因此客户端和服务器可以按照他们喜欢的任何顺序进行读写:例如,服务器可以在写入响应之前等待接收所有客户端消息,或者它可以交替读取消息然后写入消息, 或其他一些读取和写入的组合。 保留每个流中消息的顺序。
rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);
复制代码

您将在下面的 RPC 生命周期部分中了解有关不同类型 RPC 的更多信息。

Using the API

从 .proto 文件中的服务定义开始,gRPC 提供了协议缓冲区编译器插件,用于生成客户端和服务器端代码。 gRPC 用户通常在客户端调用这些 API,并在服务器端实现相应的 API。

  • 在服务器端,服务器实现服务声明的方法并运行 gRPC 服务器来处理客户端调用。 gRPC 基础设施解码传入请求、执行服务方法并编码服务响应。
  • 在客户端,客户端有一个称为存根的本地对象(对于某些语言,首选术语是客户端),它实现与服务相同的方法。 然后客户端可以在本地对象上调用这些方法,将调用的参数包装在适当的协议缓冲区消息类型中 - gRPC 负责将请求发送到服务器并返回服务器的协议缓冲区响应。

Synchronous vs. asynchronous

在服务器响应到达之前阻塞的同步 RPC 调用最接近于 RPC 所追求的过程调用的抽象。 另一方面,网络本质上是异步的,在许多情况下,能够在不阻塞当前线程的情况下启动 RPC 很有用。

大多数语言中的 gRPC 编程 API 都有同步和异步两种风格。 您可以在每种语言的教程和参考文档中找到更多信息(完整的参考文档即将推出)。

RPC life cycle

在本节中,您将仔细研究当 gRPC 客户端调用 gRPC 服务器方法时会发生什么。 有关完整的实现细节,请参阅特定于语言的页面

Unary RPC

首先考虑客户端发送单个请求并返回单个响应的最简单的 RPC 类型。 1.一旦客户端调用了一个存根方法,服务器就会收到通知:RPC 已经被调用,并且包含客户端的元数据、方法名称和指定的截止日期(如果适用)。 3.然后服务器可以立即发回它自己的初始元数据(必须在任何响应之前发送),或者等待客户端的请求消息。 首先发生的是特定于应用程序的。 3.一旦服务器收到客户端的请求消息,它就会做任何必要的工作来创建和填充响应。 然后将响应(如果成功)连同状态详细信息(状态代码和可选状态消息)和可选的尾随元数据一起返回给客户端。 4.如果响应状态为OK,则客户端得到响应,即完成客户端的调用

Server streaming RPC

服务器流式 RPC 类似于一元 RPC,不同之处在于服务器返回消息流以响应客户端的请求。 发送完所有消息后,服务器的状态详细信息(状态代码和可选状态消息)和可选的尾随元数据将发送到客户端。 这样就完成了服务器端的处理。 一旦客户端拥有服务器的所有消息,它就完成了

Client streaming RPC

客户端流式 RPC 类似于一元 RPC,不同之处在于客户端向服务器发送消息流而不是单个消息。 服务器用一条消息(连同它的状态详细信息和可选的尾随元数据)进行响应,通常但不一定在它收到所有客户端的消息之后

Bidirectional streaming RPC

在双向流式 RPC 中,调用由调用方法的客户端和接收客户端元数据、方法名称和截止日期的服务器发起。 服务器可以选择发回其初始元数据或等待客户端开始流式传输消息。

客户端和服务器端流处理是特定于应用程序的。 由于两个流是独立的,客户端和服务器可以按任意顺序读写消息。 例如,服务器可以等到收到所有客户端的消息后再写入消息,或者服务器和客户端可以玩“乒乓”——服务器收到请求,然后发回响应,然后客户端发送 另一个基于响应的请求,依此类推

Deadlines/Timeouts

gRPC 允许客户端指定在 RPC 因 DEADLINE_EXCEEDED 错误终止之前他们愿意等待 RPC 完成多长时间。 在服务器端,服务器可以查询特定的 RPC 是否超时,或者还剩下多少时间来完成 RPC。

指定截止日期或超时是特定于语言的:一些语言 API 根据超时(持续时间)工作,而某些语言 API 根据截止日期(固定时间点)工作,可能有也可能没有默认截止日期

RPC termination

在 gRPC 中,客户端和服务器都对调用的成功做出独立和本地的判断,它们的结论可能不一致。 这意味着,例如,您可能有一个 RPC 在服务器端成功完成(“我已经发送了我所有的响应!”)但在客户端失败(“响应在我的截止日期之后到达!”)。 服务器也有可能在客户端发送所有请求之前决定完成

Cancelling an RPC

客户端或服务器都可以随时取消 RPC。 取消会立即终止 RPC,以便不再进行进一步的工作。

Warning!取消之前所做的更改不会回滚

Metadata

元数据是以键值对列表的形式关于特定 RPC 调用的信息(例如身份验证详细信息),其中键是字符串,值通常是字符串,但也可以是二进制数据。 元数据对 gRPC 本身是不透明的——它允许客户端提供与服务器调用相关的信息,反之亦然。

对元数据的访问取决于语言

Channels

gRPC 通道提供到指定主机和端口上的 gRPC 服务器的连接。 它在创建客户端存根时使用。 客户端可以指定通道参数来修改 gRPC 的默认行为,例如打开或关闭消息压缩。 一个通道有状态,包括连接和空闲。

gRPC 如何处理关闭通道取决于语言。 某些语言还允许查询通道状态。

分类:
代码人生
标签:
分类:
代码人生
标签:
收藏成功!
已添加到「」, 点击更改