手动关闭dubbo provider程序,consumer端立马就打印出连接关闭的日志,但是provider并没有主动告知consumer,那么consumer是如何知道的?是consumer的心跳?是provider的shutdownHook?
都不是!
consumer发现provider掉线的调用栈如下图:
在调用 SocketChannel.read(ByteBuffer bb) 时抛出异常,和 IO 有关,所以是由底层获知连接断开的信息。
通过 wireshark 抓包进行分析:
provider 地址:192.168.40.1
consumer 地址:192.168.40.8
关闭provider程序时的通信如下图:
第69个包表示:provider进程关闭,provider所在主机给consumer发送了RST包,连接断开后,consumer还会发送SYN包重连provider,例如75和80,但是都被拒绝了。
附上TCP的一点知识:
tcp头部中含有control flag,每一位含有特殊的含义,我们只关注ACK, PSH, RST, SYN, FIN控制位。
ACK 位为1时,确认应答的字段有效。
PSH 位为1时,表示需要将收到的数据立刻传给上层应用协议。PSH为0时,则不需要立即传而是先缓存。
RST 位为1时,表示TCP连接出现异常,必须强制断开连接。
SYN 位为1时,表示希望建立连接,并设置序列号。
FIN 位为1时,表示今后不会再有数据发送,希望断开连接。