【发布时间】:2020-12-13 03:30:22
【问题描述】:
我们有一个公共 gRPC API。我们有一个客户端正在使用基于 REST 范式的 API,该范式为每个请求创建一个连接(通道)。我们怀疑他们不会在发出请求后关闭此频道。
在服务器端,有一段时间一切正常,然后似乎有些用尽了。请求在服务器上备份并且未被处理 - 这导致我们的代理超时并发送不可用的响应。重新启动服务器解决了这个问题,我可以看到在服务器关闭时在日志中刷新了备份的请求。
不幸的是,似乎没有办法监控服务器端发生的事情并修剪这些连接。我们有以下保持活动设置,但它们似乎没有影响:
grpc.KeepaliveParams(keepalive.ServerParameters{
MaxConnectionIdle: time.Minute * 5,
MaxConnectionAge: time.Minute * 15,
MaxConnectionAgeGrace: time.Minute * 1,
Time: time.Second * 60,
Timeout: time.Second * 10,
})
我们也尝试过将 MaxConcurrentStreams 从默认的 250 提高到 1000,但是 pod
我们有什么方法可以在服务器端监控通道的创建、使用和销毁——如果只是为了证明或反驳客户端的消费方法导致了问题。
详细日志记录并没有帮助,因为它似乎只记录服务器上的客户端活动(即服务器使用 pub/sub 并作为客户端记录)。我也查看了一个 channelz,但我们有相互 TLS 身份验证,我未能成功地让它在我们的生产 pod 上工作。
我们已指示客户使用单一渠道,如果无法做到,则关闭他们正在创建的渠道,但他们是一家公司,行动非常缓慢。我们也无法检查他们的代码。我们只知道他们是用dotnet开发的。我们也无法复制以类似数量运行我们自己的 go 客户端的行为。
【问题讨论】:
-
你考虑过 pprof'ing 吗?