【问题标题】:Best approach to stream multiple types with GRPC使用 GRPC 流式传输多种类型的最佳方法
【发布时间】:2018-07-31 02:20:58
【问题描述】:

我有一个将消息传递给客户端的服务器。消息具有不同的类型,服务器为客户端提供通用的handleMessagepassMessage 方法。

现在我打算对此进行调整并使用 GRPC。我知道我可以通过在.proto 文件中定义服务来公开服务器的所有方法。但是有没有办法:

  • 异构类型
  • 一次 RPC 调用
  • 使用 GRPC

oneof 允许我设置一条仅包含一个属性集的消息。我可以有一个MessageContainer,即oneof,我所有的消息类型都包含在这个容器中。现在容器只有一种类型,我只需要写一个

service {
   rpc messageHandler(ClientInfo)  returns (stream MessageContainer)
}

这样,服务器可以通过一个独特的接口将多种类型流式传输到客户端。这有意义吗?还是单独公开所有方法更好?

更新

我发现this thread 认为oneof 将是要走的路。我很喜欢这样,因为它避免了我不得不创建潜在的数十个服务和存根。它还有助于确保它是 FIFO 设置,而不是多路复用多个流并且不确定哪个消息先出现。但出于某种原因,它感觉很脏。

【问题讨论】:

  • 我认为您的更新提出的问题多于回答的问题。如果您的用例可能包含数十种“客户端可能要求服务器做的事情”,那么为什么“可能有数十种 RPC 方法定义”不是解决方案?并分享更多关于您的 RPC 方法语义的信息,这些语义激发了想要“FIFO 设置”和尽可能多的顺序?通常,重新排序会提高效率,因此分布式系统的实现是在其用例允许的情况下使用尽可能少的排序。
  • 好吧,在我的用例中,服务器会生成一堆各种类型的消息并将它们推送给客户端。现在我可以为每种类型创建一个 RPC 端点并允许客户端订阅每种类型,或者我只是将它们全部发送到同一个管道但使用不同的信封。 FIFO 会有所帮助,因为在我的情况下,它是基于回合的游戏模拟,并且每一回合的那些消息最好不要洗牌太多。
  • 是的,在这种情况下,它听起来像一个逻辑 RPC,消息的顺序听起来正是需要的。值得拆分为不同 RPC 的是与同一游戏的不同实例或不同游戏的不同实例相关联的消息——这些消息显然不需要维护顺序。

标签: java python protocol-buffers grpc


【解决方案1】:

是的,这是有道理的(您所称的 MessageContainer 最好理解为 sum type)。

...但是在可能的情况下定义不同的方法仍然更好(“更好”在这里意味着“更惯用,系统的未来维护者更易读,并且在将来需要方法语义时能够更好地改变改变”)。

将您的服务表示为返回 sum 类型的单个 RPC 方法还是多个 RPC 方法的问题归结为在 RPC 调用时是否可以知道将使用的特定加数类型。当您将request.my_type_determining_field 设置为5 时,服务器传输的流是否总是包含MessageContainer 消息,这些消息的oneof 设置为MyFifthKindOfParticularMessage 实例?如果是这样,那么您可能应该只编写一个单独的 RPC 方法来返回 MyFifthKindOfParticularMessage 消息流。但是,如果在 RPC 调用时,您确切地知道从服务器传输的消息的所用加数类型是什么(以及“具有不同加数类型的消息在相同的流”是这个的子用例),那么我认为您的服务不可能被分解为不同的 RPC,而正确的做法是使用一个 RPC 方法返回一个流总和类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 2016-05-17
    • 1970-01-01
    相关资源
    最近更新 更多