我有一个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客户端/服务器是否有任何常见错误?
我正在做的另一件事是检查连接是否打开,空闲或连接,如果是,则重新使用连接。否则,重拨。
grpc将为您管理您的连接,在需要时重新连接,因此除非您有非常特殊的需求,否则在创建它之后永远不需要监视它。
“交通正在关闭”有许多不同的原因;请参阅常见问题解答中的相关问题,如果您仍有疑问,请告诉我们:https://github.com/grpc/grpc-go#the-rpc-failed-with-error-code--unavailable-desc--transport-is-closing
经过多次搜索,我终于找到了一个可接受的逻辑解决方案来解决这个问题。
根本原因是:底层TCP连接突然关闭,但gRPC客户端和服务器都没有被“通知”此事件。
挑战在于多个层面:
我的解决方案变得相当简单:
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的能力。这是默认错误的经典案例。
我有同样的问题qazxsw poi。大约15分钟后,我让服务器关闭连接。
我的解决方案是在我的earlier this year函数上用connection
创建我的grpc.Dial
然后在每个请求上创建main
。由于pb.NewAppClient(connection)
已经创建,延迟不是问题。请求完成后,我关闭了客户端。