Go gRPC 连接保活问题

Go 实现gRPC的库质量很不错,可以适应大多数情况,基本上可以开箱即用,不用做太多设置。如单个连接的多路复用能力很强,有人实验可达8w qps,对于一般的应用,基本不用考虑使用连接池。

在连接保活环节,Go gRPC服务端缺省是允许客户端一直保持连接。这样客户端几乎不用关心连接的失效问题。但是,当gRPC服务端因异常或升级等原因重启后,Go gRPC客户端的连接就失效了。

为解决这个问题,有三种思路,一是在后台起个协程,每隔一段时间访问一下服务器,如发现连接失效则重新连接。这种方式加重服务端和客户端的负担,而且在时间间隔内还是会有失效连接的情况出现。二是在每次正式访问前,尝试访问一次服务器,如正常就继续,否则就重连接,这无疑也是加重服务端和客户端的负担。三是访问服务器出错后,检查是否因为连接不可用,如果属连接不可用,就重新连接后,再访问一次服务器。

考虑到服务器重启的概率较小,第三种解决方案对服务器、客户端资源消耗最小,只是对调用函数要求多写些代码。下面简述实现细节。

import(
         "google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)
func tryReconnect(err error) error{
        st, ok := status.FromError(err)
	if ok {
		switch st.Code() {
		case codes.Unavailable:
			//很可能是服务器重启了,重新连接
			return Reconnect()
		}
	}
        return err
}

发表评论