【问题标题】:Should I share gRPC Stubs or Channels?我应该共享 gRPC 存根还是通道?
【发布时间】:2018-04-11 20:05:03
【问题描述】:

用于创建通道的 gRPC C++ API 返回一个 shared_ptr。生成的函数 NewStub 返回一个 unique_ptr。但是我看到reports of people having issues 试图创建多个存根类型的实例,共享一个通道。他们的解决方案是共享存根。

从文档或 API 中不清楚客户端是要创建多个共享通道的存根实例还是共享单个存根。请澄清存根、通道和唯一客户端连接之间的概念关系。

潜水更深一点: 服务器可以提供多个服务,客户端端点可以使用单个通道将相应的存根类型连接到这些服务中的每一个。为此,很明显不同的存根类型共享单个通道来与服务器端点通信。 gRPC 是否期望给定服务的每个通道只有一个客户端,或者我可以在客户端端点上有多个客户端与单个服务通信?如果允许,如何在客户端端点上为给定服务实现多个客户端?服务器如何将这些区分为独立的客户端?

顺便说一句,This SO post 表示通道和存根都是线程安全的。 (这篇文章专门针对 Java,但我假设它会延续到 C++)。

【问题讨论】:

    标签: c++ client channel grpc stub


    【解决方案1】:

    我认为首先我们需要澄清 channelstub 的定义,根据official documents

    频道

    gRPC 通道提供与指定主机和端口上的 gRPC 服务器的连接...

    结论:一个通道代表一个 TCP 连接。

    存根

    在客户端,客户端有一个称为存根的本地对象(对于某些语言,首选术语是客户端),它实现与服务相同的方法。

    结论:一个存根代表一个客户端。

    通过阅读许多其他资料,我确信单通道(tcp连接)可以复用,现在我们有两种选择来实现它:

    1. 一个通道一个存根
      一个存根 多个流

    2. 一个通道 多个存根
      一个存根 多个流

    唯一的区别是是否在存根之间共享频道。我的回答是:可以,原因是:

    1. 您的 reports of people having issues 示例是用 ruby​​ 编写的,但我也可以找到站在对面的 python examples。所以行为可能取决于语言实现

    2. 同步 cpp 客户端示例使用一个 stub 对象来发出 rpc,并且它没有任何关联的流对象,那么实现多路复用目的的唯一方法就是在它们之间共享一个通道对象存根。

    综合以上两个原因,我得出结论:在 C++ 中,存根之间共享通道是有效的

    现在,回到你的问题:

    gRPC 是否期望给定服务的每个通道只有一个客户端,或者我可以在客户端端点上有多个客户端与单个服务通信?

    当然,您可以让多个客户端与单个服务通信。

    如果允许,我如何在客户端端点上为给定服务实现多个客户端?

    您可以只从一个通道或多个通道生成多个存根,前者是考虑连接开销的更好选择。

    服务器如何将它们区分为独立的客户端?

    这是由于http2的原因,它可以复用,并且有自己的规则来实现这一点,grpc需要做的就是遵循这些规则。

    希望这会有所帮助!

    【讨论】:

    • gRPC 鼓励共享频道。如果任何语言在共享频道时遇到问题,那么这是一个应该修复的错误。
    • @Ken,@Eric Anderson 是 grpc 贡献者之一。我认为他的回答是合理和权威的。我们刚刚在gitter/grpc 上进行了对话,我认为这可以让你现在大部分的困惑都清楚了。
    • 我正在研究重用为通道创建的存根的代码:在第一次使用时保持创建的静态唯一指针?是否有意义? NewStub 和存根析构函数是昂贵的操作吗?
    • 如果我的应用程序(客户端)连接到服务器,执行 RPC 并断开连接。我们还能共享连接吗?
    猜你喜欢
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 2018-07-23
    • 1970-01-01
    • 2018-06-12
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多