gRPC设置有问题。获得间歇性RPC不可用错误

问题描述 投票:3回答:3

我有一个grpc服务器和客户端,大部分时间都按预期工作,但偶尔会出现“传输正在关闭”错误:

rpc error: code = Unavailable desc = transport is closing

我想知道我的设置是否有问题。客户很基本

connection, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock())
pb.NewAppClient(connection)
defer connection.Close()

并且调用是在超时之类的

ctx, cancel := context.WithTimeout(ctx, 300*time.Millisecond)
defer cancel()

client.MyGRPCMethod(ctx, params)

我正在做的另一件事是检查连接是否打开,空闲或连接,如果是,则重新使用连接。否则,重拨。

服务器没有发生任何特殊配置

grpc.NewServer()

设置我可能正在制作的grpc客户端/服务器是否有任何常见错误?

go rpc grpc
3个回答
1
投票

我正在做的另一件事是检查连接是否打开,空闲或连接,如果是,则重新使用连接。否则,重拨。

grpc将为您管理您的连接,在需要时重新连接,因此除非您有非常特殊的需求,否则在创建它之后永远不需要监视它。

“交通正在关闭”有许多不同的原因;请参阅常见问题解答中的相关问题,如果您仍有疑问,请告诉我们:https://github.com/grpc/grpc-go#the-rpc-failed-with-error-code--unavailable-desc--transport-is-closing


5
投票

经过多次搜索,我终于找到了一个可接受的逻辑解决方案来解决这个问题。

根本原因是:底层TCP连接突然关闭,但gRPC客户端和服务器都没有被“通知”此事件。

挑战在于多个层面:

  • 内核对TCP套接字的管理
  • 任何中间负载平衡器/反向代理(由云提供商或其他方式)以及它们如何管理TCP套接字
  • 您的应用程序层本身及其网络要求 - 是否可以为将来的请求重用相同的连接

我的解决方案变得相当简单:

server = grpc.NewServer(
    grpc.KeepaliveParams(keepalive.ServerParameters{
        MaxConnectionIdle: 5 * time.Minute,           // <--- This fixes it!
    }),
)

这可确保gRPC服务器在内核或中间服务器突然终止之前正常关闭底层TCP套接字(AWS和Google Cloud Load Balancer的超时时间均超过5分钟)。

您将在此处找到的额外奖励是,您使用多个连接的任何地方,忘记关闭连接的客户端引入的任何泄漏也不会影响您的服务器。

我的0.02美元:不要盲目相信任何组织(甚至谷歌)设计和维护API的能力。这是默认错误的经典案例。


1
投票

我有同样的问题qazxsw poi。大约15分钟后,我让服务器关闭连接。

我的解决方案是在我的earlier this year函数上用connection创建我的grpc.Dial然后在每个请求上创建main。由于pb.NewAppClient(connection)已经创建,延迟不是问题。请求完成后,我关闭了客户端。

© www.soinside.com 2019 - 2024. All rights reserved.