gRPC 流式处理服务与重复字段

提示

此内容摘自电子书《为 Azure 构建云原生 .NET 应用程序》,可在 .NET 文档上获取,也可作为免费可下载的 PDF 脱机阅读。

《为 Azure 构建云原生 .NET 应用程序》电子书封面缩略图。

gRPC 服务提供两种方法来返回数据集或对象的列表。 协议缓冲区消息规范 - 使用 repeated 关键字来声明另一消息内的消息列表或数组。 gRPC 服务规范 - 使用 stream 关键字声明长时间运行的永久性连接。 通过该连接,可以发送多条消息,并可单独处理。

还可以将 stream 功能用于长时间运行的临时数据,如通知或日志消息。 但本章会考虑将它用于返回单个数据集。

应该使用哪种方法取决于以下因素:

  • 数据集的总体大小。
  • 在客户端或服务器端创建数据集所用的时间。
  • 数据集的使用者是否可以在第一个项可用时立即开始处理它,或者需要完整的数据集才能执行任何有用的操作。

何时使用 repeated 字段

对于任何大小受限且能在短时间内(例如在一秒钟之内)全部生成的数据集,你应该在普通的 Protobuf 消息中使用 repeated 字段。 例如,在电子商务系统中,创建一个订单内的物品清单可能会很快,而且清单不会很大。 返回带有 repeated 字段的单个消息比使用 stream 要快一个数量级,而且产生的网络开销更少。

如果客户端在开始处理之前需要所有数据,并且数据集足够小,可以在内存中构造,则考虑使用 repeated 字段。 即使在服务器内存中创建数据集的速度较慢,也应考虑它。

何时使用 stream 方法

当数据集中的消息对象可能非常大时,最好是使用流式处理请求或响应传输这些对象。 在内存中构造大型对象、将其写入网络,然后释放资源,这样会更有效。 此方法可提高服务的可伸缩性。

同样地,应该通过流发送无大小限制的数据集,以避免在构建数据集时内存不足。

对于使用者可单独处理每个项的数据集,如果流表示可以向用户指示进度,则应考虑使用流。 使用流可以提高应用程序的响应能力,但应将其与应用程序的总体性能进行平衡。

流可能很有用的另一种情况是跨多个服务处理消息。 如果链中的每个服务都返回一个流,则终端服务(即链中的最后一个服务)可以开始返回消息。 可以处理这些消息,并将其通过链传回给原始请求者。 请求者可以返回流,也可以将结果聚合到单个响应消息中。 这种方法非常适合于像 MapReduce 这样的模式。