conntrack -D 仅临时缓解连接跟踪表满问题,不能根治;需结合调参、源头控制及定位异常连接源才能彻底解决。

conntrack -D 清空连接跟踪表是否真能解决问题
不能直接解决,只是临时缓解。Linux 内核的 nf_conntrack 表满时,新连接会被丢弃(SYN 包不响应),conntrack -D 会清掉所有已建立、已关闭、甚至 TIME_WAIT 状态的连接条目,但只要流量模式不变,几分钟内就会再次打满。
真正要防复发,得配合调参和源头控制:
-
conntrack -D只对用户态可见条目生效,内核中已标记为不可删除(如正在被 NAT 规则引用)的条目不会被删 - 执行前建议先看下当前条目数:
conntrack -C,再用conntrack -L | head -20快速确认是否真有大量短连接残留 - 如果
conntrack -C显示接近net.netfilter.nf_conntrack_max值(比如 65536),说明表确实满了;低于 80% 却报错,大概率是内存分配失败或 slab 耗尽,不是单纯条目多
conntrack -D 的安全执行方式与常见误操作
直接跑 conntrack -D 会清空全部连接,包括还在传输中的 SSH、数据库长连接,导致运维中断或事务失败。必须加过滤条件。
最常用且安全的组合是按状态清理旧连接:
- 只删已关闭的连接:
conntrack -D --state ESTABLISHED,RELATED,INVALID(注意:这个写法实际无效,--state不支持多值逗号分隔) - 正确写法是分批执行,例如先删超时的:
conntrack -D --state CLOSE,WAIT,FIN_WAIT,TIME_WAIT - 更稳妥的是按超时时间删:比如删掉 30 秒以上没活动的条目:
conntrack -D -o extended | awk '$NF > 30 {print $1}' | xargs -r conntrack -D -s - 别在 crontab 里无条件写
conntrack -D—— 某次网络抖动导致连接堆积,自动清表可能让负载雪崩
为什么调大 nf_conntrack_max 不一定管用
单纯改 net.netfilter.nf_conntrack_max 可能触发内存不足错误,因为每个连接条目约占用 376 字节(x86_64),设成 131072 就要吃掉近 50MB 内核内存,而 nf_conntrack_buckets(哈希桶数量)默认只取 max 的 1/8,桶太少会导致哈希冲突激增,反而降低查找性能。
调整必须配套:
- 先算内存余量:
free -m看可用内核内存(非用户态)是否足够 - 同步调
nf_conntrack_buckets,推荐设为nf_conntrack_max / 4(最小 65536),否则即使 max 很大,桶不够照样撞表满 - 改完必须 reload conntrack 模块或重启网络服务,
sysctl -p仅对部分参数生效,nf_conntrack_buckets需在模块加载时指定:echo 'options nf_conntrack nf_conntrack_buckets=65536' > /etc/modprobe.d/nf_conntrack.conf
查清谁在疯狂建连接才是关键
表满从来不是孤立现象,而是上游行为异常的信号。别急着清表,先定位来源:
- 用
conntrack -L | awk '{print $5}' | cut -d= -f2 | sort | uniq -c | sort -nr | head -10查最多连接的目标 IP - 结合
ss -tn src :80或tcpdump -i any port 80 -c 100看真实流量特征(是否大量 SYN 不回复?是否源端口突增?) - 检查是否有未限制的 API 接口被刷、爬虫没设 User-Agent、或者后端服务故障导致客户端重试风暴
- 某些云厂商的 LB 健康检查会高频建连,若检查间隔小于 conntrack 超时时间(默认 30s),也会快速填满表
conntrack 表满本身不难处理,难的是区分这是瞬时毛刺还是系统性设计缺陷——比如一个没做连接池的 Python requests 脚本每秒建 200 个 HTTP 连接,清表只是给下次崩溃倒计时。










