Linux服务器在长期使用过程中,经常出现SSH会话无故断开、接口请求偶发超时、内网服务调用延迟突增等网络连接不稳定的现象。这类问题通常不会在刚部署时暴露,而是随着流量增长、链路复杂化或内核参数采用默认值而逐步显现。要彻底应对,需要从网卡层、协议栈层以及路径链路三个维度逐一排查与调优。

一、确认物理网卡与链路状态
很多连接抖动的根源其实在网卡本身。网卡降速、错包计数增长、双工模式协商异常都会直接体现为应用层连接不稳定。我们可以借助ethtool快速查看当前网卡的运行状态,而不用一上来就怀疑上层服务。
以下命令可以查看网卡速率、双工模式以及接收发送方向的错误统计:
# 查看网卡基本状态,以eth0为例 ethtool eth0 # 查看详细错误计数,重点关注rx_errors、tx_errors、crc_errors ethtool -S eth0 | grep -E 'errors|crc|drop'
如果发现crc_errors持续增长,通常说明网线、交换机端口或网卡硬件有问题;如果速度从1000Mb/s掉到100Mb/s,则要检查协商模式是否被强制修改。通过ethtool也可以手动固定速率和双工来避免反复协商带来的闪断:
# 将eth0固定为千兆全双工,避免自动协商异常 ethtool -s eth0 speed 1000 duplex full autoneg off
这种调整属于底层规避手段,实施后应持续观察一到两天,确认错包消失且业务连接不再随机中断,再固化到网卡配置文件中。
二、从协议栈层面定位连接表与端口耗尽
当单机承担较高并发时,连接不稳定常常表现为新连接无法建立、TIME_WAIT堆积或conntrack表满。此时应用日志可能只显示连接超时,但真正原因在系统内核。
使用ss命令可以直观看到不同状态的连接分布,比传统的netstat更轻量且适合排查:
# 按TCP状态统计连接数量
ss -tan | awk '{print $1}' | sort | uniq -c
# 查看当前established连接总数
ss -tan state established | wc -l
如果看到TIME_WAIT数量极大,可以通过内核参数开启端口复用,缓解客户端侧端口耗尽:
# 开启TIME_WAIT快速复用 sysctl -w net.ipv4.tcp_tw_reuse=1 # 扩大本地端口范围 sysctl -w net.ipv4.ip_local_port_range='1024 65535'
对于开启了防火墙状态跟踪的网关或容器宿主机,还要检查conntrack表容量。表满后会直接丢包,表现为随机连接失败。通过下面命令可查看使用情况:
# 查看conntrack当前条目与最大值 cat /proc/sys/net/netfilter/nf_conntrack_count cat /proc/sys/net/netfilter/nf_conntrack_max
若count长期接近max,应调大nf_conntrack_max并减少无效状态的超时时间,从而避免状态表成为网络稳定性的瓶颈。
三、TCP参数与拥塞控制调优
Linux默认的TCP协议栈以通用稳定为目标,在弱网或跨地域链路中容易因重传保守、缓冲区不足而产生连接波动。应对此类问题,核心在于调整缓存与拥塞算法。
首先可以切换到BBR拥塞控制算法,它在高延迟、易丢包链路中比传统的cubic表现更平稳:
# 临时启用bbr sysctl -w net.core.default_qdisc=fq sysctl -w net.ipv4.tcp_congestion_control=bbr # 确认当前生效算法 sysctl net.ipv4.tcp_congestion_control
其次,调大TCP读写缓冲区,使长肥管道(高带宽高延迟)能够充分利用链路,而不因缓冲区过小被误判为拥塞:
# 调整TCP内存与缓冲区范围,单位为页或字节 sysctl -w net.ipv4.tcp_rmem='4096 87380 67108864' sysctl -w net.ipv4.tcp_wmem='4096 65536 67108864' sysctl -w net.core.rmem_max=67108864 sysctl -w net.core.wmem_max=67108864
此外,针对需要长连接保活的服务,应合理设置keepalive,避免中间设备静默断连:
sysctl -w net.ipv4.tcp_keepalive_time=600 sysctl -w net.ipv4.tcp_keepalive_intvl=30 sysctl -w net.ipv4.tcp_keepalive_probes=3
上述参数修改后建议写入/etc/sysctl.conf以便重启生效,但生产环境应先在测试机验证,观察重传率和业务超时率是否下降。
四、用路径探测锁定链路故障点
当本机网卡与协议栈都正常,连接依旧不稳定,问题多半出在中间网络。此时需要用持续性路径探测来区分是本地出口问题还是运营商节点抖动。
mtr结合了ping与traceroute的能力,能持续统计每一跳的丢包与延迟:
# 持续探测目标地址,每轮显示实时丢包 mtr -n -c 100 114.114.114.114
如果第一跳就出现明显丢包,说明本机到网关的链路或网卡有问题;如果某一跳之后普遍丢包,而最后一跳目标地址反而正常,通常是该中转节点限流而非真实断连。通过连续多天在不同时段运行mtr,可以拿到链路质量的基线,为后续更换线路或提交运营商工单提供依据。
在容器或虚拟化环境中,还应检查虚拟网桥和overlay网络的健康状态,因为vxlan封装、iptables规则错乱也会表现为类似物理网络不稳定的症状。理清host与container两端的网络命名空间,才能避免错把应用层问题归因为外部网络。
五、建立常态化监控与应急机制
应对网络不稳定不能只靠故障后排查,更需要把关键指标纳入监控。通过node_exporter采集网卡错误、TCP重传、conntrack使用率,并在阈值突破时告警,可以在用户感知前发现隐患。
一个简单的重传率观察脚本如下:
# 读取TCP重传段数,两次采样求差
read a < /proc/net/snmp < <(awk '/Tcp:/ {print $13}')
sleep 10
read b < /proc/net/snmp < <(awk '/Tcp:/ {print $13}')
echo "重传增量: $((b-a))"
配合日志中的连接断开堆栈,就能快速判断是偶发闪断还是持续劣化。应急时,可临时切换备用网卡、绑定多路径或降级非核心调用,保障主链路可用。经过网卡层、协议栈层与路径层的系统调优,Linux系统的网络连接不稳定问题大多可以从被动救火转为可预期、可管控的日常运维事项。