1

双向 RPC 调用会打开多个 http2 连接吗?

我正在编写一个与我不拥有/控制的 GRPC 服务器通信的 GRPC 客户端。我正在使用@grpc/grpc-js包。有人问我这个库是否会打开到 grpc 端点的多个 HTTP2 连接,我对源代码不够熟悉,无法回答这个问题。我的拨打电话和打开流的代码如下所示

const protoLoader = require('@grpc/proto-loader')

const packageDefinition = protoLoader.loadSync(
  __dirname + '/path/to/v1.proto',
  {keepCase: true,
    longs: String,
    enums: String,
    defaults: true,
    oneofs: true
  })

const packageDefinition = grpc.loadPackageDefinition(packageDefinition).com.foo.bar.v1
const client = new packageDefinition.IngestService(
  'server.url.here.com:443',
  grpc.credentials.createSsl()
)

const stream = client.doTheThing(metadata)        

我自己已经开始研究这个问题,我发现它是启动 http2 连接Subchannel的对象,所以它似乎是每个子通道一个 http2 连接。但是,我不清楚调用、http2call 流、主通道、子通道、负载均衡器和过滤器堆栈之间的关系,我无法推断何时(如果有的话)第二个 HTTP2 连接将永远打开。

理想情况下,如果有人可以回答这个问题,双向 RPC 调用会打开多个 http2 连接吗?那太好了。如果这个答案太复杂,我会选择一个关于这些不同对象之间的关系的操作理论,这样我就可以自己推理这个,或者你可能认为会有所帮助的任何其他事情。

4

1 回答 1

3

无论请求是什么流类型,gRPC 都会使用每个连接打开多个流。这是选择 HTTP/2 作为 gRPC 底层协议的一个主要原因:将流多路复用到连接上已经是该协议的一部分。

在您提到的类中,Channel是对连接的 API 级抽象。Channel 表示与目标字符串引用的后端的任意数量的连接。它将根据需要自动建立连接以处理发起的任何请求。

Resolver您没有提到的 确定哪些后端地址与目标字符串相关联。例如,DnsResolver将查找 DNS 记录。

ALoadBalancer确定要建立哪些特定连接以及如何在这些连接之间分配请求。默认的负载均衡策略“pick first”只是将所有请求发送到首先成功建立的连接。还有“循环”负载平衡策略,它尝试建立与多个后端的连接,然后在开始调用时循环它们。

ASubchannel表示到单个后端的连接,如果它断开,可以重新建立。

过滤器堆栈对请求在顶级 API 发起和在网络上发送之间应用一些转换。

于 2020-03-31T16:48:54.027 回答