当前位置:首页>Linux>Linux性能优化:网络背后的数据流转和关键指标

Linux性能优化:网络背后的数据流转和关键指标

  • 2026-10-11 07:43:24
Linux性能优化:网络背后的数据流转和关键指标

前面我们一块探讨了在CPU、内存、磁盘等方面的Linux性能问题,以及相应的性能分析和优化方法。下面我们继续聊聊Linux网络性能,这一块内容与前面的密切相关,还未阅读前面内容的可以在文章末尾有列表跳转查看。

当你在 Linux 上执行网络数据交互时,一个请求会从终端飞到远端服务器上。如果你是搞运维的,可能你每天都在用 ss、ping、curl,偶尔也会碰到「网络慢」「连不上」「丢包」等等这些常见问题。但是可能说不清楚,数据包从你的进程出发,到飞出网卡,中间到底走了哪几步。

这篇文章不打算分析具体的原理,也不打算详解 OSI 七层模型,这些在网络上都能够查到更详细的。这篇文章主要讲一下:一个数据包在 Linux 里是怎么从无到有、从上到下、最后跑出去的,以及出问题的时候,你应该盯着哪几个指标数字。


数据包的一生:从进程到网卡

第一步:系统调用

当执行数据包发送时,进程会先调用 send()。就这么简单的一个函数,背后是一次用户态到内核态的切换。

现代操作系统不允许用户程序直接操作硬件。你的数据必须先离开用户空间,进入内核空间,才能继续往下传。这个边界就是系统调用。它不是一个轻量操作,每次 syscall 都有几百纳秒到几微秒的开销。高并发下,这个成本会被放大。

数据进入内核后,被包装成一个 sk_buff(Socket Buffer)。这是 Linux 网络栈的通用容器。从 TCP 段到 IP 包,从 RX 到 TX,几乎所有网络路径都围着 sk_buff 转。内核不移动数据本身,它只操纵 sk_buff 的指针。

第二步:传输层

sk_buff 进入传输层。

如果是 TCP,内核查 socket 状态、算 sequence number、标记 flags(SYN/ACK/FIN),加上 TCP 头部。数据太大就分片(segment)。

如果是 UDP,那简单得多。加个头部就丢给下层。UDP 不做可靠保证,所以快。代价是丢了不重传,应用层自己兜着。

这之后,sk_buff 被标注为一个完整的数据包(源 IP、目标 IP、源端口、目标端口、协议),这时就有了身份。

第三步:网络层,通过路由做转发

IP 层查路由表(ip route 看到的东西),决定包从哪个接口出去、下一跳是谁。路由背后是 FIB(Forwarding Information Base),简单理解就是:内核有张地图,send() 的时候它翻地图找出口。

目标 IP 和本机在同子网,直接发。不在,丢给默认网关。

IP 层还会检查包大小是否超过 MTU(通常 1500 字节)。超了就分片。大包拆成小包,各自带上 IP 头,到了对端再组装起来。

第四步:数据链路层

IP 层锁定了下一跳,但物理链路不认识 IP。它只认 MAC 地址。

内核查 ARP 表(ip neigh 查看)。缓存里有,直接写 MAC。没有,就广播一个 ARP 请求:"谁是 192.168.1.1?请报告你的 MAC。"

拿到 MAC 地址后,包被封装成以太网帧,准备交给网卡。

第五步:网卡驱动

以太网帧被放进 Ring Buffer(环形缓冲区)。Ring Buffer 是内核和网卡之间的共享内存区域,网卡通过 DMA(直接内存访问)从 Ring Buffer 里拿走数据,不需要 CPU 参与。

到这一步,CPU 才终于解放。前面的路由、封装、拷贝全是 CPU 在干。但数据进了 Ring Buffer,网卡硬件直接通过 DMA 拿走,CPU 可以去忙别的了。

这也是高并发下常见的瓶颈。Ring Buffer 太小,网卡消费不过来,队列满了就开始丢包。ethtool -g eth0 可以看当前大小和最大上限。

在虚拟网络,特别是容器时代

目前云计算、容器使用已经非常普遍,只管物理机的日子已经过去了。容器和虚拟机在 Linux 的网络栈上又叠了几层抽象。

  • veth pair
    ,一根虚拟网线,一端在容器里,一端在宿主机上。
  • bridge(网桥)
    ,虚拟交换机。Docker 默认搭一个 docker0,容器全接上去。
  • Network Namespace
    ,每个容器拥有独立网络栈,自己的网卡、路由表、iptables。彼此隔离。

当你在容器里 curl,数据包从容器 eth0 出发,穿过 veth 到达宿主机网桥,然后查路由、NAT 转换(容器通常是私有 IP),最后从宿主机的物理网卡出去,进入上面那五步。

每一层都有开销,也都是排查时的盲区。


网络出问题经常要查的指标

下面这几个指标覆盖了 80% 的问题。

带宽是理论上限。1Gbps、10Gbps、100Gbps,网卡规格的上限。

吞吐量才是实际传输速率。受限于 TCP 窗口、延迟、丢包。可以用 iperf 测试一下。带宽 10Gbps 但吞吐只有 2Gbps,瓶颈在协议栈或上层,不在网卡。

延迟,ping 测的就是它。延迟 = 传播延迟(光速限制)+ 处理延迟(设备处理时间)+ 排队延迟(缓冲区排队)。高延迟不一定致命,高延迟还丢包才是核心问题所在。

丢包率,用 mtr 比 ping 更精准。丢包不一定是网络不通。Ring Buffer 满了、conntrack 满了、iptables 拦了,都会丢。用 ethtool -S eth0 看硬件级丢弃,跟应用层丢包区分开。

Connection Tracking 表是最被经常忽视的。每个连接内核都跟踪状态。conntrack 表默认 65536 或 262144 条记录,满了新连接直接丢弃。conntrack -S 看使用率。高并发下偶发性断连,查这里大概率能找到根因。

Socket 缓冲区大小由 tcp_rmem 和 tcp_wmem 决定。太小,发送端被限流,接收端来不及收。太大,内存占用飙升。sysctl net.ipv4.tcp_rmem 查看,典型值是 4096 131072 6291456(最小/默认/最大)。

TCP 重传率是最直接的网络抖动信号。nstat -az TcpExtTCPSynRetrans TcpExtTCPRetransCount 看重传计数。超过 1% 说明链路不太干净了。可能拥塞,可能不稳定,可能中间设备丢包。


常用的几个命令

  • ss
    看 socket,也可以用 netstat,只是早期的命令没有ss好用
  • ip
    路由和接口管理,也可以用 ifconfig 和 route
  • tc
    流量控制,查队列和带宽限制,这个属于 iproute2 套件的一部分
  • ethtool
    网卡硬件,Ring Buffer 和驱动信息

它们覆盖了四个层面:应用层连接(ss)、网络层路由(ip)、链路层队列(tc)、物理层硬件(ethtool)。

Linux性能调优系列

- CPU篇

Linux性能优化:CPU处理进程的原理(一)

Linux性能调优:CPU处理进程的原理(二)

Linux性能调优:理解CPU中的平均负载和使用率

Linux性能调优:详解CPU使用率计算方式

Linux性能调优:CPU使用率过高的排查思路

- 内存篇

Linux性能调优:关于内存

Linux性能调优:为什么swap升高了

Linux性能调优:理解内存中的缓存

Linux性能调优:如何快速定位处理内存泄漏?

Linux性能调优:一文讲清内存问题的排查方法

- 磁盘篇

Linux性能调优:深入理解文件系统和磁盘

Linux性能调优:详解磁盘工作流程及性能指标

Linux性能调优:再谈磁盘性能指标和进程级I/O

Linux性能调优:详解FIO性能测试的几个常用场景

Linux系统调优:深入分析磁盘延迟变高的问题

Linux性能调优:常见的磁盘I/O性能优化方法

如果您有更好的理解和建议,可以免费加入知识星球,留言探讨~

最新文章

随机文章