在 RPC 系统中,服务器端会实现一组可以远程调用的方法。客户端会生成一个存根,该存根为服务器端的方法提供抽象。这样一来,客户端应用程序可以直接调用存根方法,进而调用服务器端应用程序的远程方法。

以第 2 章所讨论的 ProductInfo 服务为例,下面看一下 RPC 如何通过网络来运行。在 ProductInfo 服务中,我们实现了一个 getProduct方法,借助该方法,客户端可以通过提供商品 ID 来获取商品详情。图4-1 展示了客户端在调用远程方法时所涉及的操作。

图 4-1:通过网络实现 RPC

如图 4-1 所示,当客户端通过生成的存根调用 getProduct 方法时,可以看出如下几个关键的步骤。

  1. 客户端进程通过生成的存根调用 getProduct 方法。
  2. 客户端存根使用已编码的消息创建 HTTP POST 请求。在 gRPC中,所有的请求都是 HTTP POST 请求,并且 content-type 前缀为application/grpc。要调用的远程方法(/ProductInfo/getProduct)是以单独的 HTTP 头信息的形式发送的。
  3. HTTP 请求消息通过网络发送到服务器端。
  4. 当接收到消息后,服务器端检查消息头信息,从而确定需要调用的服务方法,然后将消息传递给服务器端骨架。
  5. 服务器端骨架将消息字节解析成特定语言的数据结构。
  6. 借助解析后的消息,服务发起对 getProduct 方法的本地调用。

服务方法的响应经过编码后被发送回客户端。响应消息会遵循我们在客户端上所观察到的相同过程(响应→编码→线路上的 HTTP 响应),该消息会被解包,它的值将返回给等待的客户端进程。

这些步骤与大多数 RPC 系统非常类似,如 CORBA、Java RMI 等。这里,gRPC 的主要区别在于消息的编码方式,如图 4-1 所示。在消息编码方面,gRPC 使用了 protocol buffers。protocol buffers 是一个语言中立、平台无关、实现结构化数据序列化的可扩展机制。只需定义数据该如何进行结构化,就可以使用专门生成的源代码,轻松地在各种数据流之间写入和读取结构化数据。

接下来深入理解 gRPC 如何使用 protocol buffers 编码消息。

文档更新时间: 2023-09-02 04:47   作者:Minho