【问题标题】:Is this an intention of bidirectional streaming RPC in gRPC?这是 gRPC 中双向流式 RPC 的意图吗?
【发布时间】:2020-04-28 15:54:43
【问题描述】:

我在执行一元 RPC 的 gRPC 客户端上用尽了我的 CPU。我想知道尝试用基本上持续整个应用程序生命周期的双向流 RPC(或它们的集合?)替换一元 RPC 是否有意义?我不知道双向流 RPC 是否适用于像这样的标准 1 请求/1 响应通信。动机是避免创建新的 TCP 连接。

【问题讨论】:

    标签: grpc grpc-go


    【解决方案1】:

    我不知道双向流式 RPC 是否适用于标准的 1 请求/1 响应通信

    如果您要使用请求-回复消息模式,只需使用一元请求-回复 (RPC)。它是为该模式和语义设计的,例如重试是众所周知的。

    动机是避免创建新的 TCP 连接。

    gRPC 使用 HTTP/2,因此所有一元 RPC 请求已经使用相同的 TCP 连接 - 因为 HTTP/2 通过相同的 TCP 连接多路复用所有请求。

    我在执行一元 RPC 的 gRPC 客户端上用尽了我的 CPU。

    这听起来有点罕见。你能改变你的沟通模式吗?在等待响应之前流式传输多个请求?替代批处理数据并很少发送更大的请求?或者您能否详细说明您的消息模式?

    【讨论】:

    • 感谢您的快速回复。至于使用相同的 TCP 连接,我想我有点困惑,因为我的 tcpdump 似乎只显示了暂时持续的 TCP 流。客户端调用是自动生成的代码(在 Go 中),它调用 ClientConn.Invoke(),它在后台调用 newClientStream()、SendMsg(),然后是 ReceiveMsg():github.com/grpc/grpc-go/blob/master/call.go。有什么我想念的吗?
    • 至于最大化 CPU,我认为我应该尝试构建一个单独的应用程序,它只执行这个 grpc,在我过分强调这个问题之前什么都不做。
    • 应该没问题。 ClientConn 代表 TCP 连接 github.com/grpc/grpc-go/blob/master/Documentation/…,您可以在同一个 ClientCon 中创建多个流。如果执行代码使您的 ClientCon 超出范围,它将被垃圾收集并且您的 TCP 连接被终止。如果您希望它保持打开状态,则必须小心处理您的连接。
    • 哦,我明白了,这是因为我一遍又一遍地调用 grpc.Dial(),所以我总是得到一个新的 ClientConn。我想我不需要这样做。
    • 您认为使用许多 ClientConns(不会超出范围)和前面的 Balancer 是否有意义? (希望我说的没错)
    【解决方案2】:

    就像@Jonas 建议的那样,为了更高的吞吐量而使用双向流是一个坏主意。

    Google 的 gRPC 团队不建议这样做,但似乎很少有人认为理论上流应该具有更低的开销。但这似乎不是真的。

    可能是因为流确保消息按照发送的顺序传递,因此当有并发消息时会产生某种瓶颈。

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

    这里详细分析:https://nshnt.medium.com/using-grpc-streams-for-unary-calls-cd64a1638c8a

    【讨论】:

      猜你喜欢
      • 2012-10-09
      • 2019-04-08
      • 1970-01-01
      • 2020-09-30
      • 2019-11-08
      • 2018-08-30
      • 2017-08-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多