Linux 网络性能与连接跟踪生产调优
Linux 网络问题经常表现为“偶发超时”“连接数高”“丢包”“CPU不高但吞吐上不去”。如果没有分层方法,很容易直接复制一组 sysctl 参数,短期掩盖症状,长期留下更难解释的风险。
本文按链路、协议栈、连接跟踪、队列、软中断和应用套接字逐层定位,并给出安全的调优与验证方法。
一、先建立分层排障思路
应用
↓ socket
TCP/UDP
↓ IP、路由、conntrack、netfilter
qdisc
↓ 网卡队列、驱动、中断
物理链路、交换机、对端
每次排障先回答:
- 是单个进程、单台主机还是整条链路;
- 是连接建立慢、传输慢还是偶发重传;
- 是入方向、出方向还是双向;
- 是所有目标还是特定目标;
- 从什么时候开始,是否与变更相关;
- 丢包发生在应用、内核、网卡还是网络设备。
二、采集基线
ip -br address
ip route
ip rule
ss -s
nstat -az
ip -s link
ethtool <interface>
ethtool -S <interface>
tc -s qdisc show dev <interface>
同时记录:
- CPU、软中断和上下文切换;
- 接口速率、双工和错误;
- MTU;
- TCP重传;
- 当前连接状态;
- conntrack 使用率;
- socket backlog;
- 应用吞吐和延迟。
没有变更前后的基线,就无法判断参数调整是否有效。
三、接口与物理层
ip -s link show dev <interface>
ethtool <interface>
ethtool -S <interface> | grep -Ei 'drop|err|miss|timeout|reset'
关注:
- RX/TX errors;
- dropped、missed、overrun;
- CRC、frame;
- 链路速率与双工;
- carrier变化;
- 网卡重置;
- 队列级丢包。
接口 drop 不一定都是物理丢包。可能来自 ring buffer、驱动、软中断处理不及时或 qdisc。
四、路由与策略路由
ip route get <destination>
ip rule show
ip route show table all
多网卡、VRF、容器网络和策略路由环境中,回程路径与入方向不同可能触发反向路径过滤或防火墙问题。
排查时同时检查:
- 源地址选择;
- 默认路由;
- policy rule优先级;
- 多路径;
- ARP/邻居表;
- rp_filter;
- 对端返回路径。
五、TCP连接状态
ss -tan
ss -s
ss -lntp
ss -tin dst <destination>
常见状态含义:
| 状态 | 可能方向 |
|---|---|
| SYN-SENT | 对端不可达、防火墙、丢包或监听不存在 |
| SYN-RECV | 半连接积压、攻击、返回包问题 |
| ESTAB | 正常,也可能是应用不释放连接 |
| CLOSE-WAIT | 本地应用未关闭已被对端关闭的socket |
| FIN-WAIT-2 | 对端未完成关闭 |
| TIME-WAIT | 主动关闭方保留状态,通常不是错误本身 |
不要看到 TIME_WAIT 多就立即修改内核参数,应先判断连接创建速率、端口范围、连接复用和应用连接池。
六、TCP指标
nstat -az | grep -E 'Tcp|Ip'
netstat -s
ss -tin
重点观察:
- RetransSegs;
- ListenOverflows;
- ListenDrops;
- TCPSynRetrans;
- TCPTimeouts;
- TCPAbortOnMemory;
- IPInDiscards;
- InNoRoutes。
单一累计值意义有限,应取两个时间点差值,结合业务流量计算速率和比例。
七、监听队列
连接建立涉及 SYN backlog 和 accept queue。
如果应用 accept 不及时,即使网卡和带宽正常,也会出现连接超时。
检查:
ss -lnt
nstat -az | grep -E 'ListenOverflows|ListenDrops'
调优需要同时考虑:
- 应用
listen(backlog); net.core.somaxconn;net.ipv4.tcp_max_syn_backlog;- 工作线程和 accept 能力;
- SYN Flood 防护;
- 上游负载均衡重试。
只调大内核队列而不修复应用处理能力,只会延后故障。
八、端口耗尽与TIME_WAIT
客户端高频短连接可能耗尽临时端口。
sysctl net.ipv4.ip_local_port_range
ss -tan state time-wait | wc -l
ss -tan state established | wc -l
优先治理:
- 使用连接池和Keep-Alive;
- 减少不必要短连接;
- 扩大客户端源IP或代理池;
- 合理扩大临时端口范围;
- 检查NAT设备端口容量;
- 观察连接关闭方向。
不要使用已经废弃或含义被误解的“快速回收”参数。
九、连接跟踪conntrack
NAT、状态防火墙和容器网络大量依赖 conntrack。
sysctl net.netfilter.nf_conntrack_count
sysctl net.netfilter.nf_conntrack_max
conntrack -S
conntrack -L 2>/dev/null | head
表满时可能出现:
nf_conntrack: table full, dropping packet
处理步骤:
- 确认 count/max 和增长速度;
- 查找连接类型、来源和目的;
- 检查短连接、扫描、NAT和异常重试;
- 核对内存余量;
- 治理连接模式;
- 再评估扩大上限和超时。
conntrack 表项消耗内存,不能无限调大。
十、软中断与多队列
mpstat -P ALL 1
cat /proc/softirqs
cat /proc/interrupts
ethtool -l <interface>
ethtool -x <interface>
如果网络软中断集中在单个CPU,可能出现吞吐瓶颈。
可评估:
- RSS;
- RPS/RFS;
- XPS;
- IRQ affinity;
- irqbalance;
- 网卡多队列;
- NUMA亲和。
调整前必须理解网卡、CPU、NUMA 和应用线程关系。盲目把中断均匀分布到所有CPU,不一定获得最佳性能。
十一、ring buffer
ethtool -g <interface>
ethtool -S <interface>
在突发流量下,ring 过小可能导致丢包。调大 ring 会增加缓冲和潜在延迟,也受驱动与硬件限制。
调整后验证:
- 网卡级 drop 是否下降;
- CPU 和软中断;
- 端到端延迟;
- 应用吞吐;
- 是否引入 bufferbloat。
十二、qdisc与排队
tc qdisc show dev <interface>
tc -s qdisc show dev <interface>
qdisc 负责出方向排队。检查 dropped、overlimits、backlog 和延迟。
场景包括:
- 默认队列;
- fq/fq_codel;
- 带宽整形;
- 优先级队列;
- 容器或虚拟机限速。
调优目标不是“队列越大越好”,而是在吞吐、突发吸收和延迟之间平衡。
十三、拥塞控制
sysctl net.ipv4.tcp_available_congestion_control
sysctl net.ipv4.tcp_congestion_control
sysctl net.core.default_qdisc
不同拥塞控制算法适用于不同网络。变更前应:
- 明确公网、专线还是数据中心网络;
- 记录 RTT、丢包和带宽;
- 在少量流量上A/B测试;
- 检查内核支持;
- 同时观察吞吐和P99延迟;
- 准备回滚。
不要因为某算法“更先进”就在所有服务器统一切换。
十四、MTU与分片
Overlay、VPN、GRE、VXLAN 和云网络会增加封装头。
ip link show
tracepath <destination>
ping -M do -s 1472 <destination>
症状包括:
- 小包正常、大包超时;
- TLS握手卡住;
- 某些网站或接口失败;
- 隧道内吞吐低;
- PMTUD被防火墙阻断。
应统一物理网络、隧道、CNI 和 Pod MTU,保留 ICMP Packet Too Big/Fragmentation Needed。
十五、卸载功能
ethtool -k <interface>
TSO、GSO、GRO、LRO 和 checksum offload 能降低CPU,但抓包时可能看到看似异常的大包或校验和错误。
诊断时要区分:
- 真正线上报文;
- 内核聚合后的视图;
- 抓包工具观察点。
临时关闭 offload 可帮助验证,但生产长期调整必须压测。
十六、抓包方法
tcpdump -ni any host <ip> and port <port>
tcpdump -ni <interface> -s 0 -w /tmp/capture.pcap
建议同时在:
- 客户端;
- 服务端;
- NAT/负载均衡两侧;
- 容器宿主机;
- 必要时交换设备镜像口。
多点抓包要校准时间。只看一侧无法判断包是未发送、途中丢失还是对端未响应。
抓包文件可能包含账号、Cookie 和业务数据,应限制权限并及时清理。
十七、DNS与网络性能
网络慢可能实际是 DNS 慢。
dig <name>
dig +trace <name>
resolvectl statistics
cat /etc/resolv.conf
检查:
- 查询延迟;
- 超时与重试;
- search domain;
- ndots;
- 多个 nameserver 的切换;
- TCP回退;
- 缓存命中;
- DNS服务器conntrack和端口容量。
容器中 ndots 与搜索域组合可能让一个短名称产生多次查询。
十八、应用层观察
内核无明显丢包时,检查:
- accept速度;
- 工作线程;
- event loop延迟;
- 连接池;
- TLS握手;
- GC暂停;
- 上游依赖;
- 限流和熔断;
- 请求体大小。
ss -tinp 可以把 socket 与进程对应,结合应用指标判断发送、接收和重传。
十九、sysctl变更方法
任何网络参数变更都应:
- 记录当前值;
- 明确问题指标和预期;
- 在单机临时应用;
- 压测和观察;
- 验证副作用;
- 小批量发布;
- 再写入持久配置;
- 保留回滚值。
配置文件中应写注释、变更单号和适用主机组。不要把网上几十行“高并发优化”直接复制到所有服务器。
二十、典型案例:高峰期偶发连接超时
现象
- CPU和带宽未满;
- 客户端偶发连接超时;
- 已建立连接大多正常;
- 高峰时新建连接失败。
排查
nstat发现 ListenDrops 增长;ss -lnt发现 accept queue 接近上限;- 应用工作线程被慢请求占用;
- 上游重试进一步放大连接数。
治理
- 修复慢依赖和线程池;
- 启用合理连接池;
- 调整应用 backlog;
- 根据压测调整 somaxconn;
- 限制上游重试;
- 增加实例并优化负载均衡;
- 监控队列和连接建立P99。
内核队列调整只是其中一环。
二十一、生产检查清单
基线
- [ ] 接口、路由、MTU、速率和队列有记录;
- [ ] TCP重传、连接状态和conntrack有趋势;
- [ ] 网卡drop、软中断和CPU有基线;
- [ ] 关键业务有端到端延迟与吞吐指标。
调优
- [ ] 先定位瓶颈层级;
- [ ] 参数变更有指标目标;
- [ ] 单机临时验证后再持久化;
- [ ] 同时观察吞吐、错误和P99延迟;
- [ ] 有明确回滚值。
故障
- [ ] 区分连接建立、传输和关闭问题;
- [ ] 检查物理、路由、TCP、conntrack、队列和应用;
- [ ] 必要时多点抓包并校准时间;
- [ ] 抓包数据受控;
- [ ] 复盘时记录根因而不是只记录“修改参数”。
参考资料
- Linux Kernel:IP sysctl
https://docs.kernel.org/networking/ip-sysctl.html - Linux Kernel:Scaling in the Linux Networking Stack
https://docs.kernel.org/networking/scaling.html - Linux man-pages:tcp(7)
https://man7.org/linux/man-pages/man7/tcp.7.html - Netfilter Conntrack Tools
https://conntrack-tools.netfilter.org/