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

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

详情如下


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为妥。

你可能感兴趣的:(开发问题解决合集,开发语言,rpc,grpc)