Node JS:双向 GRPC 调用会打开多个 http2 连接吗?

Posted

技术标签:

【中文标题】Node JS:双向 GRPC 调用会打开多个 http2 连接吗?【英文标题】:Node JS: Will a Bidirection GRPC Call Open Multiple http2 Connections? 【发布时间】:2020-07-11 15:25:59 【问题描述】:

双向 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)        

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

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

【问题讨论】:

【参考方案1】:

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

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

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

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

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

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

【讨论】:

以上是关于Node JS:双向 GRPC 调用会打开多个 http2 连接吗?的主要内容,如果未能解决你的问题,请参考以下文章

gRPC 流式调用

gRPC应用golang

基于grpc的流式方式实现双向通讯(python)

即使使用负载平衡器地址,gRPC 客户端也不使用 grpc-lb

用于双向 RPC 的 grpc-js 中未解决的 HTTP2 依赖关系

centos 7下部署grpc