如果服务器在gRPC客户端不可用时,可以采取以下等待方式:

huangapple go评论78阅读模式
英文:

Ways to wait if server is not available in gRPC from client side

问题

我希望阅读这篇文章的人一切都好。

这里有一个场景让我感到好奇:有一个全局的ClientConn用于所有向服务器发送的grpc请求。然后服务器宕机了。我想知道是否有一种方法可以等待服务器重新上线,设置一个超时时间,以便在这种情况下使用grpc更具有容错性(无论是短暂的故障还是服务器宕机)。我在想,如果客户端的clientConn状态是连接中或者是短暂的故障,就一直循环等待,如果在clientConn状态为短暂故障时超时了,就返回一个错误,因为服务器可能已经宕机。

我想知道,如果客户端有多个请求需要使用这个ClientConn,那么多个goroutine会运行这个循环,这种方法是否可行。如果有其他的替代方案、建议或者意见,我将不胜感激。

英文:

I hope who ever is reading this is doing well.

Here's a scenario that I'm wondering about: there's a global ClientConn that is being used for all grpc requests to a server. Then that server goes down. I was wondering if there's a way to wait for this server to go up with some timeout in order for the usage of grpc in this scenario to be more resilient to failures(either a transient failure or server goes down). I was thinking keep looping if the clientConn state is connecting or a transient failure and if a timeout occurs when the clientConn state was a transient failure then return an error since the server might be down.

I was wondering if this would work if there are multiple requests coming in the client side that would need this ClientConn so then multiple go routines would be running this loop. Would appreciate any other alternatives, suggestions, or advice.

答案1

得分: 4

当您调用grpc.Dial连接到服务器并接收到grpc.ClientConn时,它会自动处理重新连接。当您调用方法或请求流时,如果无法连接到服务器或处理请求时出错,它将失败。

如果错误指示是由于网络问题导致的,您可以尝试重试几次。您可以在此处检查grpc状态码https://github.com/grpc/grpc-go/blob/master/codes/codes.go#L31,并使用status.FromError从返回的错误中提取它们:https://pkg.go.dev/google.golang.org/grpc/status#FromError

您还可以使用grpc.WaitForReady选项(https://pkg.go.dev/google.golang.org/grpc#WaitForReady)来阻塞grpc调用,直到服务器准备就绪(如果处于瞬态故障)。在这种情况下,您不需要重试,但您可能应该添加一个超时来取消上下文,以便控制阻塞的时间。

如果您甚至想避免尝试调用服务器,您可以使用ClientConn.WaitForStateChange(实验性功能)来检测任何状态更改,并调用ClientConn.GetState来确定连接处于什么状态,以便知道何时安全地开始再次调用服务器。

英文:

When you call grpc.Dial to connect to a server and receive a grpc.ClientConn, it will automatically handle reconnections for you. When you call a method or request a stream, it will fail if it can't connect to the server or if there is an error processing the request.

You could retry a few times if the error indicates that it is due to the network. You can check the grpc status codes in here https://github.com/grpc/grpc-go/blob/master/codes/codes.go#L31 and extract them from the returned error using status.FromError: https://pkg.go.dev/google.golang.org/grpc/status#FromError

You also have the grpc.WaitForReady option (https://pkg.go.dev/google.golang.org/grpc#WaitForReady) which can be used to block the grpc call until the server is ready if it is in a transient failure. In that case, you don't need to retry, but you should probably add a timeout that cancels the context to have control over how long you stay blocked.

If you want to even avoid trying to call the server, you could use ClientConn.WaitForStateChange (which is experimental) to detect any state change and call ClientConn.GetState to determine in what state is the connection to know when it is safe to start calling the server again.

huangapple
  • 本文由 发表于 2022年7月26日 15:23:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/73119247.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定