当前位置:首页>Linux>Linux TCP丢包排查3天,问题竟然在内核参数里!

Linux TCP丢包排查3天,问题竟然在内核参数里!

  • 2026-09-14 15:27:22
Linux TCP丢包排查3天,问题竟然在内核参数里!
适用场景 & 前置条件
项目
要求
适用场景
TCP 连接间歇性丢包、延迟突增、偶发超时,但无法明确根因
症状
ping 正常,但 HTTP/SQL/RPC 请求超时率 1-5%;再次重试成功
OS 版本
RHEL/CentOS 7.9+ 或 Ubuntu 16.04 LTS+
内核版本
Linux Kernel 3.10+ (推荐 4.15+)
网络工具
tcpdump、wireshark、netstat、ss、iperf3
资源规格
4C8G+(需要部署监听/抓包工具)
网络要求
内网直连或公网可达;支持抓包的交换机/网卡
权限要求
root 权限(tcpdump 需要 CAP_NET_ADMIN)
技能水平
高级运维工程师,熟悉 TCP/IP、内核参数、网络诊断

反模式警告

⚠️ 以下场景不推荐按本方案排查:

  1. 1. 应用层 Bug 导致的超时,误诊为网络丢包
    • • 症状:只有特定应用超时,ping 和 iperf3 正常
    • • 原因:应用连接超时设置太短(< 500ms)
    • • 改进:先从应用日志和配置确认是否网络问题
  2. 2. 跨域/跨云厂商的网络问题
    • • 症状:A 机房到 B 机房延迟突增、丢包
    • • 原因:链路长,中间设备多,无法单点诊断
    • • 改进:联系网络运营团队,用 mtr/traceroute 定位
  3. 3. NAT/代理层丢包
    • • 症状:连接建立后立即断开,或数据断断续续
    • • 原因:LB/NAT 连接 timeout、Session 不同步
    • • 改进:检查 NAT 超时设置(通常 300-600 秒)
  4. 4. 无法获取生产环境 root 权限进行抓包
    • • 症状:tcpdump 受限,只能看应用日志
    • • 改进:在测试环境或从库复现,或申请临时权限
  5. 5. 盲目调整内核参数导致新问题
    • • 症状:丢包解决了,但引入延迟或内存溢出
    • • 改进:每次仅改一个参数,间隔 30 分钟观察

替代方案对比:

场景
推荐方案
理由
已有网络监控系统
直接查看 NetFlow/sFlow 数据
比抓包快 100 倍,全网拓扑可见
云环境(AWS/GCP)
使用云厂商 VPC Flow Logs
无需自己抓包,秒级查询
只有应用日志可用
从日志反演丢包(统计超时次数)
无需网络工具,成本最低
跨越多个运营商
使用 mtr 定位丢包点
比 tcpdump 有效找出问题链路

环境与版本矩阵

组件
RHEL/CentOS
Ubuntu/Debian
测试状态
OS 版本
RHEL 7.9+ / CentOS 8.5+
Ubuntu 16.04 LTS / 20.04 LTS / 22.04 LTS
[已实测]
内核版本
3.10.0-1160+ / 4.18.0-305+
4.15.0+ / 5.10.0+ / 5.15.0+
[已实测]
tcpdump 版本
4.9.3+
4.9.3+
[已实测]
wireshark 版本
2.6.x+ / 3.0.x+
2.6.x+ / 3.0.x+
[已实测]
netstat/ss 版本
net-tools 2.0+ 或 iproute2 4.9+
net-tools 2.0+ 或 iproute2 4.9+
[已实测]
iperf3 版本
3.6+
3.6+
[已实测]
最小资源
2C4G / 50GB
2C4G / 50GB
-
推荐资源
4C8G / 100GB
4C8G / 100GB
-
网卡
千兆+,支持 RX/TX offload
千兆+,支持 RX/TX offload
-

版本差异说明:

  • • tcpdump 4.9.3+ 支持更多协议过滤,建议升级
  • • Ubuntu 16.04 默认 kernel 4.15 之前,建议升级到 20.04
  • • RHEL 7.x 和 8.x 网络栈差异较大(BBR 算法支持度不同)

快速排查流程

  • • [ ] 前置条件检查(2分钟)
    • • [ ] 确认症状可复现(超时率稳定)
    • • [ ] 获得 root 权限(tcpdump 需要)
    • • [ ] 准备两台机器(发送端 + 接收端)
  • • [ ] 第一阶段:快速排除(5分钟)
    • • [ ] ping -c 100 target_ip 检查是否丢包
    • • [ ] netstat -s | grep -E "dropped|lost" 看是否有 drop 计数
    • • [ ] ip link show | grep -E "RX|TX" 查看网卡错误包
  • • [ ] 第二阶段:精准抓包(10-30分钟)
    • • [ ] tcpdump -i eth0 -w dump.pcap host target_ip 捕获目标流量
    • • [ ] 在另一终端重现问题(执行应用请求)
    • • [ ] 用 wireshark 离线分析 dump.pcap
  • • [ ] 第三阶段:根因诊断(10分钟)
    • • [ ] 对标 TCP 丢包 10 大根因
    • • [ ] 逐项排除(系统层 → 应用层 → 网络硬件)
  • • [ ] 第四阶段:参数优化与验证(20-60分钟)
    • • [ ] 根据诊断结果调整内核参数
    • • [ ] 部署监控告警
    • • [ ] 长期观察(至少 7 天无丢包)
    • TCP 丢包诊断三大法

诊断流程体系架构

                  应用层超时 / 丢包告警                         │                         ▼                 ┌─────────────────────┐                 │   症状初步确认      │                 │ ping/netstat/ss 检查│                 └────────┬────────────┘                          │              ┌───────────┼───────────┐              ▼           ▼           ▼         发送端      网络链路       接收端         诊断法       诊断法         诊断法        ┌──────┐   ┌──────┐      ┌──────┐        │发送  │   │抓包  │      │接收  │        │队列  │   │分析  │      │队列  │        │溢出?│   │丢包?│      │满?  │        └──┬───┘   └──┬───┘      └──┬───┘           │          │           │        通常不是      最常见      绝大多数           │          │           │           └──────────┼───────────┘                      │                根因定位→参数优化

核心判断点:

  1. 1. 发送端:netstat -s | grep "Tcp" | grep -i drop
  2. 2. 网络链路:tcpdump ... | grep -i "RST\|DUP\|RETRAN"
  3. 3. 接收端:ss -tnis | grep -i recv-q

法则 1:发送端诊断 - 排查队列溢出

目标:检查本机 TCP 发送队列是否溢出,导致数据包未能发出

诊断命令:

RHEL/CentOS:

# 方式 1:查看系统全局 TCP 统计netstat -s | grep -A 20 "Tcp:"# 预期输出示例:# Tcp:#     18452829 active connections openings#     512345 passive connection openings#     75432 failed connection attempts#     8234 connection resets received#     1024567 connections established#     45678234 segments received#     12345678 segments sended out#     4567 segments retransmitted#     0 bad segments received#     12345 resets sent# 关键指标:# - "segments retransmitted":重传次数(越低越好,>1% 表示丢包)# - "resets sent":被迫重置连接数# - "failed connection attempts":连接建立失败

Ubuntu/Debian:

# 同上,完全兼容netstat -s | grep -A 20 "Tcp:"# 若 netstat 不可用,使用 ss(新工具)ss -tnis | head -20

参数解释:

  1. 1. segments retransmitted:TCP 段重传次数
    • • 值 < 总段数 0.1% → 网络正常
    • • 值 > 总段数 1% → 明确丢包问题
  2. 2. snd_buf(发送缓冲区):查看单连接的发送队列
    # 查看所有 TCP 连接的发送缓冲使用量ss -tnis | awk '{print $2}' | sort -rn | head -10# 若 Recv-Q 和 Send-Q 都很大,说明队列堆积
  3. 3. net.core.netdev_max_backlog:网络设备队列最大深度

执行前验证:

# 确认网络接口正常运行ip link show | grep -A 2 "eth0"# 预期输出:# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> ...# 确认有网络连接ss -tnis | grep -E "ESTAB|LISTEN" | wc -l# 预期输出:数字 > 0

执行后验证 - 查看具体连接队列:

# 查看所有 TCP 连接的 Recv-Q 和 Send-Q(关键指标)ss -tnis | head -20# 预期输出示例:# State    Recv-Q Send-Q Local Address:Port         Peer Address:Port# ESTAB    0      0      192.168.1.100:46789        192.168.1.101:3306# ESTAB    1024   0      192.168.1.100:46790        192.168.1.102:3306## 说明:# - Send-Q = 0:发送缓冲正常,没有积压# - Send-Q > 0:发送缓冲积压,可能是接收端处理慢或丢包# 统计 Send-Q 不为 0 的连接ss -tnis | awk '$3 > 0 {print}' | wc -l# 若输出 > 0,说明确实有积压

常见错误与解决:

❌ 错误 1:看不到 netstat 输出(命令不存在)

# 症状-bash: netstat: command not found# 解决方案 1:安装 net-toolsyum install -y net-tools  # RHEL/CentOSapt install -y net-tools  # Ubuntu/Debian# 解决方案 2:使用 ss 替代(更新的工具)ss -tnis  # 功能等同于 netstat -tnis

❌ 错误 2:netstat 输出看不懂,数字太大

# 原始输出# segments sended out 98765432# 解决方案:用易读的方式展示netstat -s | grep "segments sended out" | awk '{printf "发送总数:%d 万\n", $4/10000}'

❌ 错误 3:LISTEN 队列溢出(SYN backlog 满)

# 症状:新连接无法建立# 诊断:查看 Listen 队列状态ss -tnis | grep LISTEN# 预期输出:# State    Recv-Q Send-Q Local Address:Port         Peer Address:Port# LISTEN   0      128    0.0.0.0:3306              0.0.0.0:*## 说明:Recv-Q 是当前连接数,Send-Q 是最大监听队列(128 可能太小)# 解决方案:增大 backlog# 编辑 /etc/sysctl.confecho"net.core.somaxconn = 65535" >> /etc/sysctl.confsysctl -p

幂等性保障:

  • • netstat -s 仅读取统计信息,不会修改系统状态

回滚要点:

  • • 发送队列溢出通常需要从应用层解决(减少请求频率或增加连接池)
  • • 内核层面可以增大队列深度,但治标不治本

法则 2:网络链路诊断 - 抓包精准定位丢包点

目标:用 tcpdump 捕获网络流量,分析是否存在丢包、重传、顺序错乱等迹象

诊断命令:

RHEL/CentOS:

# 先安装 tcpdump(通常已预装)which tcpdump || yum install -y tcpdump# 方式 1:实时抓包并显示(边抓边看)tcpdump -i eth0 -n -vvv -c 1000 \'tcp port 3306 and (tcp[tcpflags] & tcp-syn != 0 or tcp[tcpflags] & tcp-rst != 0)'# 方式 2:抓包到文件,后期用 wireshark 分析tcpdump -i eth0 -w tcp_dump.pcap -B 32000 \'tcp and (host 192.168.1.100 or host 192.168.1.101)'# 说明:# -i eth0:监听 eth0 接口# -n:不做 DNS 反解(加快速度)# -vvv:详细输出# -c 1000:抓 1000 个包后停止# -w:写入文件# -B 32000:缓冲池大小(防止丢包)

Ubuntu/Debian:

# 同上,完全兼容apt install -y tcpdumptcpdump -i eth0 -w tcp_dump.pcap 'tcp and host 192.168.1.100'

参数解释:

  1. 1. tcp[tcpflags]:TCP 标志位过滤
    • • tcp-syn:建立连接(SYN)
    • • tcp-ack:确认包(ACK)
    • • tcp-rst:重置(RST,异常断连)
    • • tcp-fin:正常关闭(FIN)
  2. 2. -B 缓冲池大小:防止高速网络下抓包丢包
    tcpdump -i eth0 -B 32000 ...  # 32MB 缓冲
    • • 默认 32KB,高速网络需要增大到 32MB
  3. 3. 过滤条件:精确抓取相关流量
    • • tcp port 3306:只看 MySQL 端口
    • • tcp and (src 192.168.1.100 or dst 192.168.1.100):只看往来某 IP

执行前验证:

# 确认 tcpdump 有足够权限tcpdump -h > /dev/null# 若无权限,用 sudo# 确认网络接口存在ip link show | grep "eth0"# 若 eth0 不存在,用 `ip link show` 查看实际接口名(可能是 ens0)

执行后验证 - 离线分析 pcap 文件:

# 第 1 步:用 tcpdump 过滤关键信息tcpdump -r tcp_dump.pcap -n | grep -E "RST|DUP|retransmission" | head -20# 预期输出:# 20:50:23.456789 IP 192.168.1.100.46789 > 192.168.1.101.3306: Flags [RST], seq 1000, ack 2000# 20:50:24.123456 IP 192.168.1.100.46790 > 192.168.1.101.3306: Flags [.], seq 3000, ack 4000, [tcp sum ok], length 1024## 若发现大量 RST 或 DUP 标记,说明确实有丢包# 第 2 步:统计丢包数量tcpdump -r tcp_dump.pcap | wc -l  # 总包数tcpdump -r tcp_dump.pcap | grep "RST\|DUP" | wc -l  # 异常包数# 第 3 步:导出为文本便于分析tcpdump -r tcp_dump.pcap -n > tcp_analysis.txt# 然后用 grep、awk 分析# 第 4 步:用 Wireshark GUI 分析(可视化)# 在本地打开 tcp_dump.pcap(通过 scp 下载到本地)scp user@remote:/root/tcp_dump.pcap ./# 在本地用 Wireshark 打开wireshark ./tcp_dump.pcap

Wireshark 分析关键指标:

在 Wireshark 中:1. 菜单 → Statistics → TCP Stream Graph → Round Trip Time   - 显示延迟曲线,突增说明有丢包2. 菜单 → Analyze → Expert Info   - 自动找出所有警告(如 Retransmission、Duplicate ACK)3. 菜单 → Statistics → Summary   - 显示总包数、平均包大小、总流量

常见错误与解决:

❌ 错误 1:tcpdump 权限不足

# 症状-bash: tcpdump: command not found或(Couldn't open device eth0: Permission denied)# 解决方案 1:用 sudosudo tcpdump -i eth0 ...# 解决方案 2:赋予普通用户权限(开发环境)sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump

❌ 错误 2:抓到的包太少或没有目标流量

# 症状:抓了 100 个包,都不是目标 IP 的流量# 可能原因:# 1. 过滤条件写错了# 2. 目标 IP 地址错误# 3. 监听的网卡不对# 诊断:tcpdump -i eth0 -n -c 20  # 不带过滤,看有什么流量# 若没看到目标 IP,说明:# - IP 地址错了# - 或在另一个网卡上# ip addr show  # 查看所有网卡和 IP

❌ 错误 3:抓包文件太大,Wireshark 打不开

# 症状:tcp_dump.pcap 文件 > 1GB,打开很慢# 解决方案 1:用 tcpdump 过滤特定时间段tcpdump -i eth0 -w tcp_dump.pcap -G 60 'tcp and host 192.168.1.100'# -G 60:每 60 秒切换一个文件# 解决方案 2:在命令行用 tcpdump 过滤后再导出tcpdump -r large_dump.pcap 'tcp.port == 3306' -w small_dump.pcap

幂等性保障:

  • • tcpdump 仅读取网络流量,不会修改系统

回滚要点:

  • • 抓包本身无需回滚,但后续根据抓包结果调整参数需要备份

法则 3:接收端诊断 - 排查缓冲区和应用处理慢

目标:检查接收端(Recv-Q)是否堆积,或应用层处理速度跟不上,导致数据丢弃

诊断命令:

RHEL/CentOS:

# 方式 1:查看接收缓冲队列(Recv-Q)ss -tnis | grep -E "ESTAB|State"# 预期输出示例:# State    Recv-Q Send-Q Local Address:Port         Peer Address:Port# ESTAB    0      0      192.168.1.100:3306        192.168.1.101:46789# ESTAB    512    0      192.168.1.100:3306        192.168.1.102:46790## 若 Recv-Q > 0,说明接收缓冲有堆积# 方式 2:查看套接字缓冲区水位cat /proc/net/tcp | awk '{print $2, $3}' | grep -v "local_address" | awk -F: '{    print $2 ":" $3, $4}' | sort | uniq -c | sort -rn | head -20# 方式 3:系统级接收队列统计netstat -s | grep -i "receive\|drop"# 预期输出示例:# 123456 packets received# 45678 packets dropped# 9876 received on raw socket

Ubuntu/Debian:

# 同上,完全兼容ss -tnisnetstat -s | grep -i "receive\|drop"

参数解释:

  1. 1. Recv-Q:TCP 接收缓冲的已收但未读数据字节数
    • • 0:缓冲正常,应用及时处理
    • "

      • 10K:有堆积,说明应用处理慢
  2. 2. 系统级丢包:/proc/net/dev 中的 RX_drop 和 RX_fifo
    cat /proc/net/dev | grep eth0# 输出格式:# eth0: RX bytes RX packets RX errors RX dropped RX overrun RX frame#       TX bytes TX packets TX errors TX dropped TX carrier TX collisns
  3. 3. 应用缓冲设置:应用的 socket 接收缓冲大小
    # 查看当前 socket 的接收缓冲cat /proc/sys/net/core/rmem_defaultcat /proc/sys/net/core/rmem_max# 通常默认 128K,高并发需要增大

执行前验证:

# 确认接收端运行正常curl http://192.168.1.100:8080/health# 预期输出:200 OK 或类似成功响应

执行后验证 - 如果发现接收队列堆积,调优:

第 1 步:增大接收缓冲

# 临时调整(立即生效,重启后失效)sysctl -w net.core.rmem_default=134217728  # 128MBsysctl -w net.core.rmem_max=134217728# 验证cat /proc/sys/net/core/rmem_default# 输出:134217728# 永久调整(编辑 /etc/sysctl.conf)cat >> /etc/sysctl.conf << 'EOF'net.core.rmem_default = 134217728net.core.rmem_max = 134217728EOFsysctl -p

第 2 步:增大网络接口的接收队列深度

# 查看当前设置ethtool -g eth0# 预期输出:# Ring parameters for eth0:# Pre-set maximums:#     RX:       4096#     RX Mini:  0#     RX Jumbo: 0#     TX:       1024# Current hardware settings:#     RX:       256        <-- 当前值太小#     RX Mini:  0#     RX Jumbo: 0#     TX:       256# 增大接收队列ethtool -G eth0 rx 2048 tx 1024# 验证ethtool -g eth0 | grep "RX\|TX" | grep -v "Pre\|Jumbo\|Mini"# 预期输出:RX 应该改为 2048

第 3 步:排查应用层处理慢的根因

# 查看应用进程的状态ps aux | grep your_app# 检查应用的系统调用延迟strace -p <app_pid> -e recv,read -T# 预期输出:# 20:50:23.456789 recv(45, ...., 65536) = 16384 <0.001234>## 若 recv 延迟 > 10ms,说明应用处理慢# 优化建议:# 1. 增加应用线程/进程数# 2. 优化应用代码的数据处理逻辑# 3. 增加服务器资源(CPU/内存)

常见错误与解决:

❌ 错误 1:ethtool 命令不存在

# 症状-bash: ethtool: command not found# 解决方案yum install -y ethtool  # RHEL/CentOSapt install -y ethtool  # Ubuntu/Debian

❌ 错误 2:增大接收缓冲后反而延迟增高

# 可能原因:缓冲太大导致内存竞争,GC 增加# 解决方案:折中方案,改为 64MB 而非 128MBsysctl -w net.core.rmem_max=67108864# 同时监控内存使用free -h# 若内存持续上升,说明缓冲设置太大

❌ 错误 3:ethtool -G 失败(驱动不支持)

# 症状Cannot get device ring settings: Operation not supported# 解决方案:这是网卡驱动限制,无法解决# 检查网卡驱动是否过旧ethtool -i eth0# 若驱动支持,升级驱动:# 一般需要升级网卡固件和驱动(厂商支持)

幂等性保障:

  • • ethtool 调整仅对当前网卡生效,重启后还原(需写入配置文件永久化)

回滚要点:

  • • 若调整后丢包反而增加,立即恢复原始值

最小必要原理

TCP 丢包的网络栈全路径

应用层(accept/recv)         ↑         │ 应用缓冲队列(Socket Receive Buffer)         │ 若满则丢包         │内核态(TCP/IP Stack)         ↑    ┌────┴─────────────────────┐    │ TCP 处理(去重、排序、确认)│    │ - 去重复的数据包        │    │ - 排序乱序包          │    │ - 发送 ACK            │    │ 若处理不及时,硬件队列满→丢包    │    ├────iperf-backlog 队列────┐    │ 接收队列满→丢包          │    │    ├─网卡驱动(RX ring)────┐    │ 若网卡缓冲溢出→丢包    │    │    └─────网络物理层──────┘

三个关键决策点

  1. 1. 发送端 → 网络链路:数据包能否成功发出?
    • • netstat -s 看重传率
    • • 若重传率 > 1%,说明网络链路不稳定
  2. 2. 网络链路 → 接收端:数据包能否完整到达?
    • • tcpdump 看是否有丢包迹象(RST、DUP、超时)
    • • 若丢包 > 0.1%,说明网络环境有问题
  3. 3. 接收端 → 应用层:应用能否及时处理?
    • • ss -tnis 看 Recv-Q 是否堆积
    • • 若 Recv-Q > 缓冲的 20%,说明应用处理慢

常见丢包原因的信号

丢包信号
可能根因
验证命令
高重传率
网络丢包、RTT 抖动
netstat -s | grep retransmit
Recv-Q 堆积
应用处理慢、缓冲太小
ss -tnis | grep "ESTAB"
网卡 RX_drop 高
网卡队列满、驱动问题
cat /proc/net/dev
连接重置(RST)
TCP 协议栈异常、防火墙
tcpdump ... | grep RST
都不是
可能是应用层 bug
查看应用日志

可观测性:监控 + 告警 + 性能基准

Linux 原生监控

# 实时监控 TCP 丢包关键指标watch -n 1 'netstat -s | grep -E "segments|dropped|retrans|reset"'# 预期输出(每秒刷新一次):# 123456 segments received# 45678 segments sended out# 234 segments retransmitted# 12 connection resets received# 34 resets sent

Prometheus 监控规则

# 保存为 tcp_packet_loss_rules.ymlgroups:-name:tcp_packet_lossinterval:30srules:# 重传率过高告警-alert:TCPHighRetransmitRateexpr:|          rate(node_tcp_segments_retransmitted_total[5m]) /          rate(node_tcp_segments_total[5m]) > 0.01for:5mlabels:severity:warningannotations:summary:"TCP 重传率过高,超过 1%({{ $labels.instance }})"description:"重传率:{{ $value | humanizePercentage }}"# 接收缓冲堆积告警-alert:TCPReceiveQueueBacklogexpr:|          node_sockstat_TCP_inuse /          node_sockstat_TCP_alloc > 0.8for:5mlabels:severity:criticalannotations:summary:"TCP 接收队列堆积率超过 80%"# 连接重置告警-alert:TCPConnectionResetsexpr:rate(node_tcp_connections_resets_total[5m])>10for:5mlabels:severity:warningannotations:summary:"TCP 连接重置频率过高({{ $labels.instance }})"description:"每秒重置数:{{ $value }}"# 网卡丢包告警-alert:NetworkInterfacePacketLossexpr:|          rate(node_network_receive_drop_total[5m]) > 100 or          rate(node_network_transmit_drop_total[5m]) > 100for:5mlabels:severity:criticalannotations:summary:"网卡每秒丢包超过 100({{ $labels.device }})"

性能基准测试

场景 1:模拟正常网络传输

# 在接收端运行服务器nc -l -p 5000 > /dev/null  # nc 监听 5000 端口# 在发送端运行 iperf3 客户端(模拟大流量)iperf3 -c 192.168.1.100 -p 5000 -t 60 -i 10 -R# 预期输出(发送端视角):# [ 10] 0.00-10.00 sec 125 GBytes 1.07 Gbps 0 datagrams# [ 10] 10.00-20.00 sec 125 GBytes 1.07 Gbps 0 datagrams## 关键指标:# - datagrams 为 0:没有丢包# - Gbps 稳定:网络链路正常

场景 2:在 CPU 高负载下测试丢包

# 在接收端启动 CPU 密集任务stress --cpu 8 --timeout 120s &# 同时运行 iperf3 传输iperf3 -c 192.168.1.100 -t 60 -i 10 -R# 对比 CPU 空闲 vs 高负载下的丢包率# 若高负载下丢包率 > 低负载 10 倍,说明 CPU 不足

场景 3:长期稳定性测试(24+ 小时)

# 脚本:持续监控丢包指标并告警#!/bin/bashwhiletrue; do# 每 60 秒采样一次  RETRANS=$(netstat -s 2>/dev/null | grep "segments retransmitted" | awk '{print $1}')  DROPS=$(cat /proc/net/dev | grep eth0 | awk '{print $4}')echo"$(date) - 重传:$RETRANS,网卡丢包:$DROPS" >> /tmp/stability_test.log# 若丢包突增(对比前一次),告警if [ $DROPS -gt 1000 ]; thenecho"告警:网卡丢包数异常:$DROPS" | mail -s "丢包告警" admin@company.comfisleep 60done

总结:TCP 丢包 10 大根因

优先级
根因
核心症状
修复方案
🔴高
应用缓冲溢出
Recv-Q 持续 > 1MB
增大接收缓冲:sysctl -w net.core.rmem_max=134217728(128MB)+ 优化应用处理速度
🔴高
网卡队列满
/proc/net/dev 中 RX_drop 增加
ethtool -G eth0 rx 2048 tx 1024
(增大网卡接收队列)+ 升级驱动
🔴高
SYN_RECV 队列溢出
新连接建立失败
启用 SYN cookie:sysctl -w net.ipv4.tcp_syncookies=1
🔴高
应用 Bug
仅特定应用丢包
查看应用日志 + 修复代码
🟡中
防火墙丢包
特定端口 / IP 丢包
iptables -L -v
 查看 DROP 计数 → 调整规则
🟡中
TCP backlog 满
新连接失败
echo "net.core.somaxconn=65535" >> /etc/sysctl.conf && sysctl -p
🟡中
网络链路抖动
ping RTT 时高时低
检查交换机 / 路由器配置
🟡中
TCP 重传超时
连接建立慢、频繁超时
sysctl -w net.ipv4.tcp_retries2=15
(增加重传次数)
🟡中
MTU 不匹配
大包丢、小包正常
统一网卡 / 交换机 MTU 为 1500:ip link set eth0 mtu 1500
🟠低
内核 Bug
无规律丢包
升级内核版本

往期推荐

点亮,服务器三年不宕机

最新文章

随机文章