dmesg -l err,warn 可快速定位内核因 nf_conntrack 表满或内存不足导致的套接字回收,典型提示包括“nf_conntrack: table full, dropping packet”“TCP: out of memory”“sk_alloc: no more mem”,需配合 grep -i 精准筛选,且必须结合 /proc/sys/net/nf_conntrack_count 与 max 实时验证表状态。

dmesg -l err,warn 查看内核主动回收套接字的原始提示
内核在内存或连接跟踪表(nf_conntrack)耗尽时,会直接向 ring buffer 写入警告或错误,这类日志不会出现在 /var/log/messages 或 journalctl -u 服务日志里,必须用 dmesg 实时抓取。典型现象是连接突然中断、新建连接超时,但 ss -tuln 看不到异常状态。
执行以下命令能快速定位:
dmesg -l err,warn | grep -i -E "conntrack|table full|drop|oom|socket|alloc"
-
dmesg -l err,warn只输出错误和警告级别,避免被 info 级别消息淹没 - 必须加
grep -i,因为内核日志大小写不统一(如nf_conntrack和NF_CONNTRACK都可能出现) - 常见关键字符串:
"nf_conntrack: table full, dropping packet"、"TCP: out of memory"、"sk_alloc: no more mem"
journalctl -k --since "1 hour ago" 按时间范围过滤内核套接字回收事件
journalctl -k 虽然底层也读 ring buffer,但它支持时间过滤和结构化查询,适合复现问题后回溯。当 dmesg 输出被新日志覆盖时,journalctl 可能还保留着几小时内的记录(取决于 journald 的存储配额)。
例如排查最近一次连接丢包:
journalctl -k --since "30 minutes ago" | grep -i "conntrack\|socket\|oom"
-
journalctl -k默认需要sudo才能读取完整内核日志(普通用户可能被权限策略限制) - 如果返回空,不代表没发生——可能是
journald配置了Storage=volatile,只存内存中,重启即清空 - 对比
dmesg -T和journalctl -k -T的时间戳是否一致,可判断日志是否被截断
检查 /var/log/kern.log 是否记录了 conntrack 耗尽事件
部分系统(尤其是启用了 rsyslog 并配置了 imklog 模块的)会把 dmesg 输出自动转存到 /var/log/kern.log。这个文件有持久化优势,但内容可能比 dmesg 少——因为 rsyslog 默认只转发 err 和 warn,且可能丢弃高频重复日志。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
查看方式:
sudo tail -50 /var/log/kern.log | grep -i "table full\|conntrack"
- 注意路径差异:
/var/log/kern.log在 Debian/Ubuntu 常见;RHEL/CentOS 通常走/var/log/messages,需配合grep kern - 如果该文件为空或无更新,说明
rsyslog未启用内核日志转发,或imklog模块未加载(检查rsyslog.conf中是否有$ModLoad imklog) - 不要依赖
cat /var/log/kern.log | grep查历史——它可能已被logrotate归档为kern.log.1.gz,需用zgrep
确认 conntrack 表是否真的已满:实时验证比查日志更可靠
很多“套接字被回收”的误判,其实源于没确认当前 nf_conntrack 表状态。日志只是结果,而 /proc/sys/net/nf_conntrack_count 和 /proc/sys/net/nf_conntrack_max 才是直接证据。
执行:
echo "count: $(cat /proc/sys/net/nf_conntrack_count), max: $(cat /proc/sys/net/nf_conntrack_max)"
- 若
count接近或等于max,基本可断定是 conntrack 表满导致丢包,此时dmesg日志里的"table full"就不是噪音 -
nf_conntrack_max默认值常偏低(如 65536),高并发短连接场景极易打满;调整需改/etc/sysctl.conf,不能只靠查日志 - 临时清空表(仅调试):
sudo conntrack -F,但清空后若负载未降,日志会立刻重现——这说明问题在流量模型,不在日志本身
真正难定位的不是日志在哪,而是内核在资源紧张时可能跳过日志直接丢包。比如 sk_alloc 失败时,某些内核版本根本不记日志,只静默返回 -ENOMEM。所以看到连接异常,先看 /proc/sys/net/nf_conntrack_count 和 free -h,再翻日志,顺序不能反。

















