conntrack表满新连接被丢弃:仅调 sysctl 无效,hashsize 需按 nf_conntrack 模块参数配置

来源:互联网 时间:2026-11-03

早上九点,客服说网站打不开,你在服务器上ping外网是通的。同一时间老用户的页面还能刷出来,新开的连接一律超时。重启服务没用,因为问题不在服务上。

内核跟踪每条连接的状态,这张表叫conntrack,NAT和状态防火墙都靠它。表满之后新连接的数据包直接被丢弃,内核日志里只有一行nf_conntrack: table full, dropping packet。丢包发生在网络层,应用根本没收到请求,所以PHP和nginx的日志里什么都没有。这张表管NAT,云主机的出网映射也靠它,影响面大。表项老化有默认时间,TCP已建立的连接是5天,这条默认值在nf_conntrack_tcp_timeout_established里。5天太长,短连接堆积的时候等不到它自己消失。改短有风险,正常的长连接会被中途拆掉。

表多大由nf_conntrack_max决定,默认值跟内存挂钩,几个G的机器常见是6万多到13万。容器里这份额度更小,宿主机分给命名空间的那份先用完。这个数在/proc里能直接读到。

cat /proc/sys/net/netfilter/nf_conntrack_count看当前条数,跟max比一下就知道还剩多少。conntrack -C也能读,装了conntrack-tools才有这个命令。dmesg | grep conntrack能看到丢弃发生的时间点。连不上但能ping通,是这张表满了的典型表现。能ping通只说明三层可达,被丢的是需要新建表项的握手包,ICMP回显同样占表项。ssh也连不上,只能从控制台进。

一条表项占三百字节上下,13万条约40兆,内存代价不高。真正要算的是每条连接活多久,短连接多、TIME_WAIT长,表就周转不过来。网站前面挂了CDN,回源连接数比访客数少很多,这一层能顶一阵。按峰值连接数配,不要按平均值。

占表最多是看不见的流量。DNS查询走UDP,每条占一项,几十秒才老化,机器多的时候能占掉一半。conntrack -L输出按源地址排一遍,占得最多的那几台就是嫌疑。这类流量目的地址少、频率高。

调大分两步,先改max再改hashsize。hashsize是桶数,一般取max的四分之一,桶太少链长,查表变慢。max写进/etc/sysctl.conf,sysctl -p生效。hashsize是模块参数,不是sysctl键,写进/etc/modprobe.d/nf_conntrack.conf,重启后生效。改完会重建哈希表,已有连接不断。

改完用sysctl -w临时验一下,观察一天的count峰值。峰值长期贴着上限的八成,说明还得再加,或者该从连接源头收。sysctl -w是临时的,重启就回原值,验证完记得落盘。容器里的值要在宿主机上调。

确实绕不开的流量可以打NOTRACK标记,raw表里对特定端口做-j NOTRACK,这些包不进conntrack。用之前确认没有依赖状态匹配的规则,否则防火墙会漏。这类规则写在filter表之前,顺序不能错。

这套调完,早高峰的丢弃归零,客服那边的反馈也跟着停了。conntrack这类问题不会写进应用日志,得先想到内核这一层才查得到。下次再遇到能ping通但连不上的情况,先看这一层。

相关文章

A5创业网 版权所有

返回顶部