[Linux翻译]用gRPC实现快速的IPC(第一部分)。

841 阅读7分钟

原文地址:medium.com/@chittorash…

原文作者:medium.com/@chittorash…

发布时间:2018年7月22日-6分钟阅读

image.png

图片来自grpc.io/

你可能听说过这个街区里的酷小孩,自从Roy Fielding在2000年写下论文后,他就一直在敲打着人们的神经。自此,REST风靡全球,没有任何严重的竞争。REST架构的理念激发了科技行业的一些创新,它已经成为开发者API和服务交互的事实标准。OpenAPI / SwaggerGraphQL等规范是RESTful浪潮的明确继承者,并彻底改变了我们向消费者暴露数据的方式。

随着REST在暴露我们的客户端API方面的巨大应用,以及微服务架构的出现,将同样的学习转移到使用REST来实现我们的服务间通信(又称IPC)是很常见的。虽然REST对于单体来说工作得很好,具有诸如--人类可读性、易于测试以及客户端和服务器之间的松散耦合等优点,但在微服务架构中,它肯定会落后,因为在微服务架构中,你有无状态的实例和聊天的接口。使用REST进行服务间交互的一些主要缺点可以是--------。

  1. 维护API合同是很困难的(虽然OpenAPI在一定限度内解决了这个问题,但稍后再谈)。
  2. JSON在线缆和CPU上都很困难,因为它被设计成人类可读的,并作为纯文本通过线缆发送。
  3. 流式传输对HTTP/1.1来说,从根本上来说是很困难的。

所以作为一种选择,许多公司已经有了自己的内部工具,用于服务间的通信(不管它是否基于HTTP)。这种一个服务调用另一个服务的场景被称为IPC或进程间通信。IPC的一个特殊情况是远程过程调用或简称RPC,在这种情况下,一个服务内部的方法可以调用另一个方法,而这个方法可能位于其他服务内部(可能在不同的地址空间或在不同的物理机器上),就像任何其他本地方法一样。

牢记以上所有的背景,让我们来看看什么是gRPC,以及它如何解决上面提到的REST的一些问题,同时也给我们提供了很棒的功能。


什么是gRPC?

gRPC是谷歌的一个开源RPC框架。它被设计成具有很高的性能,并且可以在多种环境和语言中实现。

gRPC的主要卖点是它的速度和在微服务风格架构中实现多语言服务的能力。你也可以用它来连接移动和浏览器客户端到你的服务器。其他优点包括通过HTTP/2的双向流,以及可插拔的负载均衡、认证和监控。

gRPC的动机和设计原则。

和大多数大型科技公司一样,谷歌长期以来一直使用微服务架构来运行其大部分服务。而由于这个原因,他们有一个名为Stubby的通用RPC框架来连接他们分布在数据中心的微服务。让所有的服务都实现了一个通用的框架,从而实现了诸如易于监控、更快的迭代、安全性和可靠性等等。

然而,Stubby并不是通用的,而且其中有太多Google的影子(双关语意为😛)。考虑到Stubby与Google的基础设施紧密耦合,团队觉得有必要对Stubby进行进化,于是决定分拆一个新的项目,旨在实现Stubby能做的所有事情,同时也保持一个开放的通用设计。他们甚至从其他广泛标准化的项目中获得了灵感,如SPDY、HTTP/2等。

关于gRPC背后的设计原理,请阅读官方页面

那么你为什么要关心呢?

到目前为止,我们已经讨论了REST的优点和缺点。现在让我们来看看gRPC在面对面的包装。

  1. 静态类型化和版本化的接口--gRPC使用IDL(接口定义语言),即协议缓冲区(Protocol Buffer)来定义rpc服务及其请求和响应模型。协议缓冲区带有一个类型系统,因此允许我们结构化消息的类型,并允许在编译时检测类型不匹配。此外,版本化的API变得很容易,因为添加或删除请求和响应模型的键不会破坏现有的客户端实现。在接下来的章节中,我们将更详细地讨论协议缓冲区。

  2. 效率和稳定性--默认情况下,协议缓冲区被设计成在线路上是高效的。这允许在服务之间进行更快的数据传输。REST的调用和等待模型受到流模型的挑战,从而提供更好的系统稳定性。类型化系统的本质和向后兼容的模型使得系统具有坚实的稳定性。

  3. 多语言服务--拥有一个IDL和跨多种语言的客户端-服务器存根,允许gRPC用户采用多语言方式,为不同的微服务选择不同的语言。

  4. 超时和请求取消--gRPC为服务的请求取消和超时提供了开箱即用的解决方案。每个调用都可以携带超时字段,当请求在我们的微服务栈中传播时,这些字段会被用来计算新的超时。

  5. 日志和指标--gRPC提供了简单的扩展以插入日志和监控系统,如Zipkin

  6. 双向侧流--通过HTTP/2的支持,我们得到了像流这样的功能,它允许请求和响应的非阻塞I/O模型。这不是REST世界的情况,在那里,请求会阻塞一些资源,直到数据被聚合为响应.同时,通过gRPC,我们得到了双向流,从而允许一个更好的模型来传输数据,而不是聊天的RESTful APIs。

它不会为你解决什么问题?

好吧,gRPC不仅仅会让你的API设计更好。你仍然可以写出设计糟糕的gRPC端点,然后逃之夭夭。API的设计如果在gRPC的世界里被认为是一个实现细节,因此是留给实现者的。所以在写API之前要三思而行。

什么是协议缓冲区?

Protocol Buffer是一个高性能、开源的二进制序列化协议,它允许轻松定义服务和自动生成客户端库。与gRPC类似,Protocol Buffer编译器可用于许多流行的语言和平台。

与XML和JSON等其他数据交换格式相比,协议缓冲区和更快、更轻、更简单、更清晰。它们提供了从各种来源编译数据和更新结构的功能,并打破了旧的编译结构。

协议缓冲区示例

当以协议缓冲区格式编写结构时,我们定义的消息是这里的封装单位。这些消息是通过导线序列化,并在另一端去序列化。请看下面的例子

message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;


  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

关于原语的一些事情需要注意的是--。

  1. 消息中的每个字段都有一个类型(string, int32, bool甚至其他消息类型)。这使得类型系统2. 可以在编译过程中强制进行静态类型检查。
  2. 每个字段都有一个与之相关联的唯一编号的键。密钥是消息编码方案的一个组成部分。 字段也可以被标记为必填、可选或重复。
  3. 你可以运行编译器来获得语言特定的访问器/存根类。通过它们,你可以得到读写消息的ter和setter方法。
  4. 另外,更新(添加或删除)消息中的字段不会破坏旧的二进制文件。新的字段只是被旧的二进制文件所忽略。双赢!

关于协议缓冲区语言规范的更多信息,请查看proto3规范

进一步阅读

请继续关注并查看第二部分,我们将在NodeJS中实现一个gRPC Todo App。


通过www.DeepL.com/Translator(免费版)翻译