首页/系统/Linux 内核与性能调优速查/跟踪表状态分布统计
网络栈调优98 条

跟踪表状态分布统计

按状态统计连接跟踪条目, 快速发现 SYN_RECV 堆积、大量 UNREPLIED 或关闭态残留。

连接跟踪与状态统计

conntrack 是 Linux netfilter 的连接跟踪表,iptables 与 nftables 的 NAT、state 匹配都建立在它之上。每条跟踪条目记录一个会话的五元组、方向标记与 TCP 会话状态。只看条目总数分不出问题在哪,按状态归类才能区分正常长连接与堆在半连接、未回复阶段的异常条目。观察对象是内核的 nf_conntrack 模块,命令来自 conntrack-tools 包。

基本信息

适用平台Linux(netfilter,iptables 与 nftables 共用同一张表)
依赖模块nf_conntrack,用 lsmod 或 /proc/net/nf_conntrack 确认已加载
权限要求root 或 CAP_NET_ADMIN
表上限/proc/sys/net/netfilter/nf_conntrack_max

典型使用场景

  • NAT 网关与四层负载均衡排查偶发连接失败:先看表容量是否接近上限,再看堆积的是哪一类状态。
  • 怀疑遭受 SYN Flood:半连接条目大量堆积,同时内核同步队列溢出与 cookie 计数上涨。
  • 回程不通定位:未回复标记的比例升高,说明去程到了、回包没看到,指向路由、ARP 或上游策略。
  • 发布前后对比:用状态占比判断是握手阶段失败,还是连接建好了但应用没有接受。
  • 老连接清理:确认等待关闭的条目是否因超时参数过大长期占用跟踪表。

状态分布统计

状态分布统计
conntrack -L 2>/dev/null | grep -oE 'ESTABLISHED|TIME_WAIT|SYN_SENT|SYN_RECV|CLOSE_WAIT|LAST_ACK|FIN_WAIT|UNREPLIED' | sort | uniq -c | sort -rn   # 按状态归类计数
conntrack -C                                     # 当前条目总数,比遍历全表快得多
cat /proc/sys/net/netfilter/nf_conntrack_count   # 与上面对照,确认口径一致
cat /proc/sys/net/netfilter/nf_conntrack_max     # 表上限,接近时新连接会被丢弃
conntrack -L -p tcp --dport 8080 2>/dev/null | head   # 只看某端口的条目,缩小范围
conntrack -S                                     # 内核侧插入失败与丢包计数

状态含义与判读

状态含义正常与异常
ESTABLISHED双向都有流量,会话已建立正常主体,突降说明业务中断
UNREPLIED只观察到发起方向,回程缺失少量正常,比例升高查回程路径
SYN_RECV半连接,握手未完成持续堆积多为队列满或源地址伪造
TIME_WAIT主动关闭后等待超时结束量大但稳定属正常
CLOSE_WAIT对端已关闭,等本端关闭长期堆积说明应用没调用关闭
只有 TCP 条目才显示握手类状态;UDP、ICMP 这类无连接协议只有未回复标记与超时时间,不要拿 TCP 状态去套。
跟踪表写满时新连接被直接丢弃,表现为随机超时或间歇失败。先看条目数与上限的比值、再看内核日志有没有表满告警,不要一上来就调大上限掩盖泄漏。

易错点

  • 只数条目总数不分类,定位不到阶段:先按状态归类,再按源目地址收敛到具体会话。
  • 在几十万条的巨表上反复全量列出:遍历开销大且拖慢排查,先用计数命令看总量、按协议与端口过滤后再展开。
  • 把条目的源目方向读反:回程元组对应回复方向,读错会得出「请求没到」的错误结论,用事件流模式观察更可靠。
  • 忽略表满的连锁反应:上限触顶时丢的是新连接而不是老连接,业务表现为偶发失败,容易误判为应用故障。
  • 不看内核计数:插入失败与丢弃计数能区分是被放弃还是从未匹配上规则,缺了这一步结论只能靠猜。

数据来源与参考

  • man conntrack(8)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌