我应该共享gRPC存根或频道吗?

时间:2017-10-30 18:36:35

标签: c++ client channel grpc stub

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

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

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

除此之外,This SO post表示Channels和Stub都是线程安全的。 (这篇文章专门针对Java,但我认为它会延续到C ++)。

1 个答案:

答案 0 :(得分:0)

我认为首先我们需要根据official documents澄清 channel stub 的定义:

频道

  

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

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

存根

  

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

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

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

  1. 一个频道<->一个存根
    一个存根<->多个流

  2. 一个频道<->多个存根
    一个存根<->多个流

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

  1. 您的reports of people having issues示例是用ruby编写的,但我也可以发现python examples站在另一侧。因此,行为可能取决于语言的实现方式

  2. 同步cpp客户端示例使用一个存根对象来发布rpc,并且它没有任何与之关联的流对象,然后实现多路复用的唯一方法是仅在其中共享一个单个通道对象存根。

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

现在,回到您的问题:

  

gRPC是否希望给定服务的每个通道仅一个客户端,或者我可以在客户端端点上与单个服务对话的多个客户端?

当然,您可以有多个客户端在同一个服务进行对话。

  

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

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

  

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

这是由于http2引起的,它可以多路复用,并且具有自己的规则来实现这一目标,grpc要做的只是遵循这些规则。

希望这会有所帮助!