解决grpc连接Dial成功状态却变为TransientFailure

2023-12-31 13:49:52

?如有帮助,欢迎留下足迹哦!

详情如下


code = Unavailable desc = connection error: desc = "transport: Error while dialing dial tcp 192.168.31.33:9001:?
connectex: No connection could be made because the target machine actively refused it."

此时连接状态为?TransientFailure

目录

背景

现象汇总

分析与解决

总结与附录


背景


GRPC客户端与服务端建立连接时我们都知道需要先Dial,报该错时实际上Dial操作是成功的,此时err为nil,但调用rpc接口时失败,报了该错。

现象汇总


1,? 将客户端与服务端均放在本机,且地址写本机地址时也报改错,Dial成功,调用rpc接口失败;
Dial成功时的连接状态为Connecting,调用rpc接口失败前的连接状态变为TransientFailure;
?? ?
??这两状态是什么意思呢?看下源码:

?? ?const (
?? ?// Idle indicates the ClientConn is idle. Idle 表示 ClientConn 处于空闲状态。
?? ?Idle State = iota
?? ?// Connecting indicates the ClientConn is connecting. ?Connecting 表示 ClientConn 正在连接。
?? ?Connecting
?? ?// Ready indicates the ClientConn is ready for work. Ready 表示 ClientConn 已准备好工作。
?? ?Ready
?? ?// TransientFailure indicates the ClientConn has seen a failure but expects to recover. ?TransientFailure 表示 ClientConn 已经看到失败但希望恢复。
?? ?TransientFailure
?? ?// Shutdown indicates the ClientConn has started shutting down. ?Shutdown 表示 ClientConn 已经开始关闭。
?? ?Shutdown
)


2, 将客户端与服务端均放在本机,且地址写127.0.0.1时成功,调用rpc接口也成功,一切正常;

3,将客户端与服务端均放在不同主机,且启动服务地址写127.0.0.1、客户端连接地址写服务端ip时失败也报改错,Dial成功,调用rpc接口失败;

不禁让人纳闷,到底是哪的问题?


分析与解决

以上现象出现时,服务端所在主机已开放了端口号为9001的tcp端口,因此排除端口开放问题;

另外,客户端与服务端均在本机时可成功,而在不同主机不成功,就说明了大概率还是网络不通方面的问题;

与此同时进行抓包,发现有从客户端流向服务端主机的包且端口正确,但来回都是R.和S的标记交替着,服务端给客户端一直回复R. 表明连接异常一直在被重置,同时这样的回复实际也和服务端未启动服务时的情形一致;

根据以上现象,基本确定是客户端没有识别到服务端的启动(实际上服务端启动着)

最终一步步摸排得知,启动服务时监听地址写的是:

net.Listen("tcp", fmt.Sprintf("%s:%s", "127.0.0.1", 9001))

以下几种写法均正常:

net.Listen("tcp", fmt.Sprintf(":%s", 9001))
net.Listen("tcp", fmt.Sprintf("%s:%s", "本机IP", 9001))
net.Listen("tcp", fmt.Sprintf("%s:%s", "0.0.0.0", 9001))

其中第一、三个启动后打印出来的服务地址是[::]:9001
第二种是 ip:9001

总结与附录

那么总结一下原因,实际上就是127.0.0.1启动时仅本机可连接成功,只作用在本机,因为它是本机回环地址,
正常的网络包从3层进入2层,然后发出去,而发向回环地址的包,直接在IP层短路了,也就是发到IP层时直接被IP层接收、不再向下发送;
也就是说对于本机单机测试时可以直接用127.0.0.1。

1、如果监听地址是127.0.0.1:port,表示仅监听环回接口的数据,即本机发送给本机port端口的数据,其他主机发送过来的数据无法接收到。
2、如果监听地址是0.0.0.0:port,表示监听所有网络接口的数据,包括回环接口和其他网络接口,所有本机和其他主机发送的数据都可以接收到。
3、如果监听地址是本机ip:port,表示仅监听本机ip对应的网络接口。仅接收目的地址是本机ip的数据。(对本机发送给本机这种情况,如果目的主机地址是127.0.0.1则,收不到,仅当目的主机地址是本机ip时能够收到)。

实际上0.0.0.0风险较大,建议使用本机IP为妥。

文章来源:https://blog.csdn.net/HYZX_9987/article/details/135213749
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。