【问题标题】:gRpc bidirectional streamgRpc 双向流
【发布时间】:2019-04-08 07:22:11
【问题描述】:

假设我在服务器上有 2 个函数加法和减法。我可以在这种情况下使用双向流来增加吞吐量吗?如果是这样,我是否必须为每个请求和响应提供一个标识符以区分客户端的响应(如 reqId)?通常,它们将是一元调用,但希望通过流式传输来增加吞吐量。

【问题讨论】:

  • 您是否对一元 RPC 的吞吐量进行了基准测试? AFAIK,gRPC 将重用 RPC 服务的开放通道,因此吞吐量增加可能不会那么显着。而且它还剥夺了您通过运行服务器副本来大幅提高吞吐量的能力。
  • @Michał - 您能否详细说明“通过运行服务器副本大幅提高吞吐量的能力”?当与主机的连接打开时,运行多个服务器如何帮助提高吞吐量?谢谢。
  • 当您执行流式 RPC 时,它必须在单个服务器计算机上执行。您可以部署多台服务器机器并将它们放在反向代理后面 - 在这种情况下,每个请求都可以由不同的机器处理。如果客户端要发送多个一元请求,允许您同时处理多个请求。如果客户端要发送流式请求,则需要在单台机器上执行该请求。
  • @Michał - 我的理解是,对于 gRPC(它在内部使用 Http/2),当连接打开时,它总是在两台机器之间,并且对于后续请求保持打开状态。这是 http/1 和 http/2 之间的主要区别。那么,您所说的关于由不同机器处理的多个一元请求是否正确,因为它涉及与不同机器打开如此多的连接?我错过了什么吗?

标签: grpc grpc-java


【解决方案1】:

流式消息的开销确实低于一元 RPC。尽管 gRPC 团队倾向于不鼓励仅仅为了提高性能而使用流,除非确实有必要,因为消息不能分发到多个后端、一个后端的多个线程上,而且调试起来更加复杂和困难。尽管如果您正在考虑使用一元 RPC 进行批处理,那么流式传输确实具有您可能更喜欢的优势。

如果服务器按照接收请求的顺序计算响应,那么您不需要 reqId;第一个响应将针对第一个请求,第二个针对第二个,第三个针对第三个等。gRPC 流保留消息顺序。

【讨论】:

  • 谢谢。在我们的例子中,服务器不会按顺序计算响应。因此,我们将不得不使用 reqId。当您说“消息不能分发到多个后端,一个后端的多个线程”时,您能否分享更多信息(任何文章)?
【解决方案2】:

使用双向流来提高吞吐量是个坏主意。

对于较低的并发请求,两者都有相当的延迟。 但是,对于更高的负载,一元调用的性能要好得多。

流确保消息按照发送的顺序传递,这意味着如果有并发消息,就会出现某种瓶颈。

没有明显的理由我们应该更喜欢流而不是一元,因为使用流会带来额外的问题,例如:

  • 我们有并发价格请求时延迟很短
  • 应用程序级别的复杂实现
  • 缺乏负载平衡:客户端将连接一台服务器并忽略任何新服务器

这里有一些基准的详细分析:https://nshnt.medium.com/using-grpc-streams-for-unary-calls-cd64a1638c8a

【讨论】:

    猜你喜欢
    • 2020-09-30
    • 1970-01-01
    • 2018-08-30
    • 2021-03-29
    • 2018-04-26
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    相关资源
    最近更新 更多