凌晨的业务告警往往不是应用进程崩溃,而是 Linux 主机上的连接跟踪表接近上限:既有请求变慢,新连接又间歇性超时。表面看像网络抖动,实际内核可能已经没有空间创建新的跟踪状态,于是把后续连接直接丢弃。只调整应用连接池、盲目重启服务,往往只能短暂缓解,真正需要确认的是连接跟踪表容量、端口资源,还是防火墙规则本身出了问题。
如果你正在选机器,或者想先把线路和配置跑通再谈长期方案,可以先看看这几家的线路说明和技术参数:cloudnium(海外服务器),先看清带宽线路、流量策略和退款条款,再决定要不要迁。
为什么表满了,新连接会被丢弃
Linux 的 netfilter 连接跟踪模块会为每个需要跟踪的连接建立状态条目,例如 TCP 会话、UDP 映射以及部分 ICMP 通信。条目创建后,会依据连接状态和超时策略进入回收流程;TCP 的 状态条目回收机制决定了已经结束或长时间没有进展的会话何时释放空间。表未满时,nf_conntrack_count 通常会随着业务流量上升;达到 nf_conntrack_max 后,新的跟踪请求无法继续创建,内核通常记录相关丢弃计数,并让上层表现为连接建立失败、重传或超时。
这并不等于“应用连接数等于表容量”。短连接风暴、NAT 后多协议流量、异常扫描和长连接堆积,都可能让 nf_conntrack_count 高于应用侧看到的并发数。排查时还要观察 SYN_SENT、SYN_RECV、ESTABLISHED、TIME_WAIT 等状态,以及 nf_conntrack_count 与 nf_conntrack_max 的比例。表接近上限时,即使应用线程仍然空闲,内核也可能先丢弃新状态。

如何判断是容量、端口还是规则问题
先看三个方向。第一,读取 nf_conntrack_count 和 nf_conntrack_max,确认使用量是否贴近上限,并结合 nf_conntrack_count 的增长速度估算连接条目消耗。容量估算可以按“峰值并发连接数 ÷ 有效存活时间对应的回收速率”计算,再预留短连接突发和异常流量空间;不能只看当前 ESTABLISHED 数量,因为处于其他 TCP 状态的条目同样占用表项。
第二,排除临时端口耗尽。客户端连接远端服务时,若大量连接复用同一源 IP,源端口可能先耗尽,表现为 bind 或 connect 失败;此时 nf_conntrack_count 可能并不高。应检查 ephemeral 端口范围、已用端口数量、TIME_WAIT 数量以及 nf_conntrack_max,不能把端口不足误判成跟踪表溢出。可在测试机用 ServLlama 汇总连接跟踪、端口和防火墙计数,减少人工翻日志的误差。
第三,检查规则。规则数量过多、链式匹配过深、重复的 DROP 策略或异常流量,都会让新建连接在规则遍历阶段失败。规则丢包一般不会表现为跟踪表计数达到上限,需要对照规则命中计数、丢弃原因和系统日志判断。告警可设置 nf_conntrack_count 达到 nf_conntrack_max 的 80% 预警、90% 严重告警,并同时监控增长速度和丢弃计数。

应急处置应先保留现场计数和日志,再确认是否存在异常连接来源;确认是容量问题后,临时调高 nf_conntrack_max 并同步调整回收参数,观察计数是否回落。调高上限不是无限制扩容方案,还应结合主机内存、临时端口范围和业务连接池复核,避免把异常流量转化为更高的资源占用。
回收滞后与临时端口耗尽
状态条目回收并非与连接关闭同步完成。连接关闭后,内核会保留表项一段时间,用于识别后续报文并维护 NAT 状态,回收由协议超时参数决定。因此,nf_conntrack_count 可能明显高于 ss 看到的活跃连接数。客户端的 TIME_WAIT 会占用临时端口,服务端的 CLOSE_WAIT 偏多,则常指向应用没有及时关闭套接字。
UDP 没有握手,表项通常按空闲超时回收;持续流量可能进入 stream 状态。大量 UDP、ICMP 和 NAT 映射同样会占用表项,不能只按 TCP 数估算容量。nf_conntrack_max 只是创建上限,日志出现 nf_conntrack: table full, dropping packet 才是表满的直接证据。
临时端口耗尽是另一层限制。主动出站连接受 ip_local_port_range 约束,同一源地址到同一目标还受四元组唯一性限制。即使表项仍有空间,端口池过小也会触发 EADDRNOTAVAIL 或建连超时。此时应观察 SYN_SENT、建连速率和重试风暴;扩大端口范围只能缓解症状,修复连接泄漏和异常重试才是根治。
调整时最容易踩的坑,是把所有异常都归因于 nf_conntrack_max。盲目提高上限会增加内存压力,也可能加重哈希桶竞争;未经验证就调整超时,还可能误伤长间隔业务流量。

因此,应按业务流量分布设定 TCP 与 UDP 超时,并区分普通 UDP 会话和 stream 会话。变更前后要保留错误率、丢包率及 NAT 重置次数,确认回收加快没有引入新故障。
可执行的检查清单
建立基线:以 root 执行
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max和conntrack -S,同时记录ss -s、free -h。重点看 new、drop、early_drop、error 是否与业务尖峰同步。核对状态:高峰期先只读计数,避免反复全表扫描;低峰期用
conntrack -L抽样 TCP、UDP、TIME_WAIT、CLOSE_WAIT、UNREPLIED。大量正常短连接要评估超时和连接复用;UNREPLIED 异常增长则排查 SYN 洪泛、错误目标地址及回包丢失。核对端口:读取
ip_local_port_range,统计新建连接速率及SYN_SENT。若只是端口耗尽,提高 nf_conntrack_max 不会增加临时端口。对齐证据:用
dmesg | grep nf_conntrack查找 table full 和丢弃时间戳,并关联 NAT 规则、UDP 映射及代理状态,排除重复会话与异常回包。处置验证:先修复连接泄漏、异常重试和未释放的 UDP 会话,再依据内存余量调整容量或超时参数。变更后持续观察表项比例、丢弃计数、端口占用率和业务错误率。
最终要区分三件事:连接跟踪表容量不足、状态条目回收机制偏慢,以及临时端口耗尽。先用计数、状态分布、内核日志和端口数据证明故障落在哪一层,再调整参数;盲目扩容既可能无效,也会掩盖应用侧的连接生命周期问题。


喜欢
顶
难过
囧
围观
无聊





