nf_conntrack表满会导致新连接被内核直接丢弃,引发超时、502等故障;根本原因是连接未及时回收,而非单纯流量突增;秒级恢复应通过切换nf_conntrack_tcp_be_liberal触发哈希表重建,而非conntrack -F或重启模块。

为什么 nf_conntrack: table full 会瞬间打挂服务
这不是日志警告,是内核连接跟踪表已满的硬性拒绝信号。新连接(尤其是短连接、DNS 查询、健康检查)会被直接丢弃,表现为超时、502、curl: (7) Failed to connect。根本原因不是流量突增,而是连接未及时回收——比如后端响应慢、客户端不发 FIN、NAT 设备复用率低,或 nf_conntrack_max 设置过小。
秒级清空 conntrack 表的可靠方式
别用 conntrack -F:它逐条删除,高并发下可能卡住甚至触发 soft lockup;也别重启 netfilter 模块,会中断所有连接。真正秒级生效的是重置整个哈希表:
-
echo 1 > /proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal(可选,让 TCP 状态判断更宽松,加快老化) -
echo 1 > /proc/sys/net/netfilter/nf_conntrack_tcp_loose(默认开启,确保非标准握手也能被跟踪) -
echo 0 > /proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal(临时关闭 liberal 模式,强制内核重建 conntrack 表) - 立刻再写回
echo 1 > /proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal,触发表重建
这个操作实际耗时 cat /proc/sys/net/netfilter/nf_conntrack_count,数值应立即归零或大幅下降。
防止复发的关键参数调优
清空只是急救,防复发必须从三方面入手:
-
扩容表大小:根据内存和连接峰值估算,
nf_conntrack_max建议设为内存(MB) × 16(例如 32GB 内存 →echo 524288 > /proc/sys/net/netfilter/nf_conntrack_max) -
加速老化:缩短非活跃连接存活时间,
echo 300 > /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established(从默认 432000 秒压到 5 分钟) -
精准过滤:对明确不需要连接跟踪的流量禁用,如本机 loopback 或特定 UDP 日志上报:
iptables -t raw -A PREROUTING -i lo -j NOTRACK,再加-A OUTPUT -o lo -j NOTRACK
注意:修改 /proc/sys/ 下参数是临时的,需写入 /etc/sysctl.conf 并执行 sysctl -p 持久化。
哪些场景下调大 nf_conntrack_max 反而有害
不是越大越好。当 nf_conntrack_max 超过物理内存能支撑的哈希桶数量时,内核会退化为链表查找,单条连接匹配延迟从 O(1) 变成 O(N),反而拖慢所有网络路径。典型症状是 softirq CPU 占用飙升、netstat -s | grep "packet drops" 显示大量 drop。建议监控 /proc/net/nf_conntrack 行数 + nf_conntrack_count,长期维持在 nf_conntrack_max × 0.7 以内最稳妥。










