问题:
JDBC直连数据库执行存储过程,每次2小时11分都中断
报错:
com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
The last packet successfully received from the server was *** milliseconds ago. The last packet sent successfully to the server was **** milliseconds ago.
Caused by: java.net.SocketException: 连接超时 (Read failed)
分析:
2小时11分网上搜索了,计算恰好满足tcp探测时间
linux服务器tcp探测包
tcp_keepalive_time:7200s
tcp_keepalive_tntvl: 75s
重试次数9次
7200+75*9 = 2小时11分
cat /proc/sys/net/ipv4/tcp_keepalive_time
echo "3600" > /proc/sys/net/ipv4/tcp_keepalive_time
尝试修改为1小时,结果有时可以完成但是仍有1小时11分问题,猜测tcp探测不通
tcpdump抓包:
timeout 7200 tcpdump -i 网卡号 host 192.168.1.101 >>tcp.log
设置7200s自动抓取指定网卡,指定ip的tcp包输出到文件中
日志格式分析:
13:57:02.953358 IP 127.0.0.1.11118 > 192.168.1.101.mysql: Flags [.], ack 5402, win 352, options [nop,nop,TS val 461533184 ecr 770639880], length 0
IP 发送者>接受者
Flags [S.]表示这个TCP数据包被设置了SYN(同步)标志。TCP协议中,SYN标志用于在建立连接时同步双方的序列号,是建立连接过程中必不可少的一个步骤。当一个TCP连接建立时,一个SYN包会被发送到另一方,接收到SYN包的一方会回复一个ACK+SYN包,确认同步,然后连接建立成功。因此,如果在tcpdump日志中看到Flags [S.],表示这是一个连接建立过程中的SYN包。
Flags [P.]表示TCP数据包被设置了PUSH标志。TCP的PUSH标志用于告诉接收方立即处理数据,而不是在接收缓冲区有足够的空间时再处理。这个标志通常与ACK标志(确认)一起使用,表示确认的数据已经准备好可以被发送了
Flags [F.]表示这个TCP数据包被设置了FIN(结束)标志。TCP协议中,当一个连接的一方要关闭连接时,它会发送一个FIN包到另一方,表示它已经完成了数据发送,不再需要发送更多数据。接收到FIN包的另一方可以选择关闭连接或者继续发送数据。如果另一方也想要关闭连接,它应该发送一个ACK包来确认接收到FIN包,然后关闭连接。如果另一方还想继续发送数据,它应该忽略这个FIN包,然后继续发送数据。
Flags [R.]表示这个TCP数据包被设置了RST(重置)标志。TCP协议中,RST标志用于重置一个连接。当一个连接被关闭或者因为其他原因需要立即关闭时,一方会发送一个RST包到另一方,另一方接收到RST包后,会立即关闭连接,并丢弃所有待处理的数据。注意,如果一个连接被正常关闭,应该是先发送FIN包,然后等待对方确认关闭,而不是发送RST包。所以如果在tcpdump日志中看到Flags [R.],可能表示连接被异常关闭或者出现了其他问题。
Flags [.]表示TCP数据包的标志位字段,其中没有任何标志被设置。具体来说,这意味着这个TCP数据包没有任何特殊的标志,如PUSH、ACK、RST(重置)、SYN(同步)、FIN(结束)等。这是一个常见的情况,表示数据包在网络传输过程中是正常的。如果还有其他标志被设置,那么这些标志会以[.]前面的形式在日志中显示出来。
握手过程参照:
结果:
多次抓包分析,有的是探测包按时到没有回应,又的是探测包半小时后到达,猜测目标服务器繁忙或者网络问题
验证猜想:
将数据库迁移到其他机器上解决