网络栈调优98 条

连接跟踪表满诊断

nf_conntrack_count 接近 nf_conntrack_max 时,新连接会被丢弃并出现 table full 日志;先治连接泄漏再谈扩容。

表满意味着什么

nf_conntrack_count 是当前连接跟踪表里的表项数量,一旦逼近 nf_conntrack_max,新的连接就无法建立跟踪条目而被丢弃,内核日志会出现「nf_conntrack: table full, dropping packet」。处理顺序应是先治连接泄漏与超时配置,再考虑扩容上限——单纯抬高 max 会让内存占用同步上升,还会掩盖连接没有被正常回收这一根因。

基本信息

当前用量/proc/sys/net/netfilter/nf_conntrack_count
上限/proc/sys/net/netfilter/nf_conntrack_max
溢出证据/proc/net/stat/nf_conntrack 中的 insert_failed 与 drop 计数
内核日志dmesg 中的 table full 提示
相关超时nf_conntrack_tcp_timeout_established 等决定表项存活时间
辅助工具conntrack -S(统计)、conntrack -C(表项数)

典型使用场景

  • 新连接偶发失败并伴随 table full 日志,需要快速确认是否表满
  • NAT 网关或负载均衡的容量评估,短连接场景尤其敏感
  • 宿主上连接数异常增长:应用未正确关闭连接导致表项残留
  • 排查表项被长时间占用:结合超时参数判断回收是否过慢
  • 遭遇扫描或攻击时,快速判断表项是否被打满并采取限速措施

诊断步骤

诊断步骤
cat /proc/sys/net/netfilter/nf_conntrack_count  # 当前表项数
cat /proc/sys/net/netfilter/nf_conntrack_max  # 表项上限
dmesg -T | grep -i -m5 'table full'  # 是否已经出现新连接被丢弃的日志
awk '{print $1, $9, $15}' /proc/net/stat/nf_conntrack | head  # 查看每 CPU 的 insert_failed 等计数
conntrack -S 2>/dev/null | head  # 汇总统计(需 conntrack-tools)
sysctl net.netfilter.nf_conntrack_tcp_timeout_established  # 已建立连接表项的保留时长
cat /proc/net/nf_conntrack 2>/dev/null | wc -l  # 抽查表项规模(需要相应权限)

证据链对照

项目位置判读要点
nf_conntrack_count/proc/sys/net/netfilter/与 max 的比值就是水位
nf_conntrack_max同目录上限本身也需要评估内存代价
insert_failed/proc/net/stat/nf_conntrack插入失败次数,溢出的直接证据
table full 日志dmesg明确提示新连接被丢弃
相关超时值nf_conntrack_tcp_timeout_*决定表项被无效占用的时间
短连接高频场景下,调小相关超时(尤其是已建立连接的表项保持时间)往往比单纯扩容更有效,因为它直接减少表项被无效占用的时长,从源头降低水位。
表项数量异常增长时不要只做扩容:应同时排查是否存在连接未正常关闭、中间设备静默丢包导致表项残留、或扫描类流量冲击,否则扩到多大都只是推迟问题发生。

易错点

  • 只扩容 max 不查泄漏根因:内存上升且问题在一段时间后重新出现
  • 不做证据确认就判断表满:insert_failed 与内核日志才是可靠依据
  • 忽略日志中的 table full:这是最明确的线索,漏看会延误定位
  • 超时设置过长:已断开的连接长期占用表项,水位虚高
  • 不考虑内存代价:每条表项都占内存,扩容必须与整体容量一起规划

数据来源与参考

  • Linux 内核 Documentation/networking/nf_conntrack-sysctl.rst
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌