要看实时网卡吞吐量,优先用 watch -n 1 'cat /proc/net/dev | grep eth0' 或 ip -s link show eth0 计算差值,单位为字节/秒;ethtool 显示的是协商速率而非实际负载。

怎么看实时网卡吞吐量,别用 ifconfig
ifconfig 显示的是累计字节数,没法直接看出当前速率,容易误判瞬时瓶颈。真要看实时收发(MB/s、pps),优先用 ss + cat /proc/net/dev 或更轻量的 ip -s link。
- 运行
watch -n 1 'cat /proc/net/dev | grep eth0',两次输出相减再除以 1 就是每秒字节数(注意单位是字节,不是比特) -
ip -s link show eth0的rx/tx packets和bytes字段也支持差值计算,比ifconfig更准且无弃用风险 - 别信
ethtool eth0里的 “Speed” —— 那只是协商速率,不代表实际负载,满速跑 UDP 丢包时它照样显示 10000Mb/s
tcpdump 抓包为什么一开就丢包,怎么调缓冲区
默认 tcpdump 使用内核 packet capture ring buffer,太小(通常 2MB 左右),高流量下直接溢出丢帧,现象是抓到的包明显少于 netstat -s | grep "segments retransmited" 统计。
- 加
-B 8192把缓冲区提到 8MB(单位是 KB),适合千兆以上链路;-B 32768对万兆网卡更稳妥 - 配合
-w /tmp/out.pcap直接写磁盘,避免 stdout 重定向引入额外延迟 - 别在
ssh会话里边tcpdump边grep—— 管道会拖慢捕获,改用-f过滤表达式(如tcpdump -f 'port 8080 and tcp[12] & 0x80 != 0')
为什么 netstat -s 显示大量 “retransmits”,但应用层没报错
TCP 重传不等于连接失败,很多场景下是正常重试:弱网丢包、接收方 delayed ACK、中间设备乱序。关键是看重传率是否持续 > 1%,以及是否伴随 tcplife 中的连接异常终止。
- 查重传率:
awk '/segments retransmited/ {r=$1} /segments sent/ {s=$1} END {printf "%.2f%\n", r/s*100}' /proc/net/snmp - 确认是否由接收窗口阻塞导致:
ss -i看每个连接的rwnd(接收窗口)是否长期为 0 或极小 - 云环境常见干扰源:虚拟交换机限速、安全组底层丢包、ENI 驱动 bug(比如某些旧版
ena驱动在突增流量下会静默丢 ACK)
调整 net.core.somaxconn 后还是有 connection refused
net.core.somaxconn 只控制内核 listen backlog 队列长度,真正压垮服务的往往是应用层 accept 速度跟不上,或队列满了后内核直接丢 SYN(表现为客户端超时,而非 RST)。
- 必须同步调大应用的
listen()第二个参数(如 Nginx 的listen ... backlog=4096),否则系统参数无效 - 检查是否被 cgroup 限制:
cat /sys/fs/cgroup/pids/xxx/pids.current和/sys/fs/cgroup/memory/xxx/memory.max,OOM killer 杀掉 worker 进程也会导致监听中断 - SYN Flood 防御开启时(
net.ipv4.tcp_syncookies = 1),net.ipv4.tcp_max_syn_backlog才起作用,这个值要 ≥net.core.somaxconn
网络栈的瓶颈从来不在单个 sysctl 参数上,而在于内核队列、驱动环形缓冲区、应用 accept 循环、甚至 CPU 调度优先级之间的咬合。改一个值前,先用 perf record -e 'syscalls:sys_enter_accept* 看 accept 是否卡住,比盲目调参靠谱得多。










