iptables nf_conntrack 条目的老化时间因该连接发生丢包而变短,进而导致连接中断的问题

起因

  程序在执行长时间sql时总会提示网络中断,connection reset。

问题分析

  分别检查数据库服务器和客户端的连接发现,服务端的连接已经释放了,客户端好像还在等待超时。由于两台机器之间有通过iptables配置的nat服务,又在nat服务器检查,发现客户端还未断开时,nat记录也不见了。
  查看转发记录表/proc/net/nf_conntrack发现数据库连接的老化时间和其连接的老化时间相比短 了很多。当老化时间到了的时候,转发链就被删了,当然就不通了。
  google得知已建立的连接的默认的老化周期由内核参数 net.netfilter.nf_conntrack_tcp_timeout_established控制,默认值是432000秒(5天)。但如果此连接发生丢包,从抓包情况看只要丢一个包,老化周期就会变得非常短(300秒),超过300秒后该转发条目就没了,导致内外网两端的应用虽然还保有连接状态,但实际上已经联不通了。
  从文章
https://stackoverflow.com/questions/56733622/connection-reset-by-peer-with-driver-2-8-0-and-mongo-4-0-9-on-a-k8s-cluster/57496563#57496563
看变短的300秒受参数nf_conntrack_tcp_timeout_max_retrans控制,默认是300,调整这个值后,新增的丢包的连接的老化时间会跟着变化。

解决方案

  没有google到nf_conntrack_tcp_timeout_max_retrans的任何说明,也没有找到网络中丢包的原因。由于nf_conntrackb表负载不大,也极少丢包。因此目前的解决方案是直接将nf_conntrack_tcp_timeout_max_retrans改为=432000来解决,忽略丢包的影响。

遗留问题

为啥丢包?

  从抓包的情况看,每次数据库连接池创建连续建立10个连接后,的短暂交互基本都会发生丢包,但后面大规模导入数据时基本不丢包

为什么内核会在转发连接丢包时将老化时间改为300秒?

  没有找到 nf_conntrack_tcp_timeout_max_retrans的说明文档,不知为啥google不到这个参数的说明,不知道这里面的原理是啥,也不知道改了会有啥影响不。

内核网站说明中
https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl.txt
nf_conntrack_tcp_max_retrans

其他

centos7查看 conntrack记录

cat /proc/net/nf_conntrack

输出列表中的第五列即为老化时间,正常情况下enstablished的连接都会很长

wireshark分析丢包

过滤条件 tcp.analysis.retransmission

参考

连接跟踪详解
https://www.cnblogs.com/huenchao/p/6225770.html

© 2020, 新之助meow. 原创文章转载请注明: 转载自http://www.xinmeow.com

0.00 avg. rating (0% score) - 0 votes
点赞