性能指标有哪些?
10.1 如何查看网络的性能指标?
Linux 网络协议栈是根据 TCP/IP 模型来实现的,TCP/IP 模型由应用层、传输层、网络层和网络接
口层,共四层组成,每一层都有各自的职责。

应用程序要发送数据包时,通常是通过 socket 接口,于是就会发生系统调用,把应用层的数据拷
⻉到内核里的 socket 层,接着由网络协议栈从上 到下逐层处理后,最后才会送到网卡发 送出去。
而对于接收网络包时,同样也要经过网络协议逐层处理,不过处理的方向与发送数据时是 相反
的,也就是从下 到上的逐层处理,最后才送到应用程序。
网络的速度往往 跟用⼾体验是挂钩的,那我们又该用什么 指标来衡量 Linux 的网络性能呢?以及如
何分析网络问题呢?
这次,我们就来说这些。

性能指标有哪些?
通常是以 4 个指标来衡量网络的性能,分别 是带宽、延时、吞吐 率、PPS (Packet Per Second ),
它们表示的意义如下:
带宽,表示链路的最大传输速率,单位是 b/s (比特 / 秒),带宽越大,其传输能力就越强。
延时,表示请求数据包发 送后,收到对端响应,所需要的时间延迟。不同的场景有着不同的含
义,比如可以表示建立 TCP 连接所需的时间延迟,或一个数据包往返所需的时间延迟。
吞吐 率,表示单位时间内成功传输的数据量,单位是 b/s (比特 / 秒)或者 B/s (字节 / 秒),吞吐受带宽限制,带宽越大,吞吐 率的上限才可能越高。
PPS ,全称是 Packet Per Second (包 / 秒),表示以网络包为单位的传输速率,一般用来评估系
统对于网络的转发能力。
当然,除了以上这四种基本的指标,还有一些其他常用的性能指标,比如:
网络的可用性,表示网络能否正常通信;
并发连接数,表示 TCP 连接数量;
丢包率,表示所丢失数据包数量占所发送数据组的比率;
重传率,表示重传网络包的比例;
你可能会问了,如何观测这些性能指标呢?不急,继续往下看。
网络配置如何看?
要想知道网络的配置和状态,我们可以使 用 ifconfig 或者 ip 命令来查 看。
这两个 命令功能都差不多,不过它们属于不 同的软件包, ifconfig 属于 net-tools 软件包,
ip 属于 iproute2 软件包,我的印象中 net-tools 软件包没有人继续维 护了,而 iproute2
软件包是有开发者依然在维护,所以更推荐你使 用 ip 工具。
学以致用,那就来使用这两个 命令,来查 看网口 eth0 的配置等信息:

虽然这两个 命令输出的格式不尽相同,但是输出的内容基本相同,比如都包含了 IP 地址 、子网掩
码、MAC 地址 、网关地址 、MTU 大小、网口的状态以及网络包收发的统计信息,下面就来说说 这
些信息,它们都与网络性能有一定的关系。
第一,网口的连接状态标志。其实也就是表示对应的网口是否连接到交换机或路由器等设备,如
果 ifconfig 输出中看到有 RUNNING ,或者 ip 输出中有 LOWER_UP ,则说明物理网络是连通
的,如果看不到,则表示网口没有接网线。
第二,MTU 大小。默认值是 1500 字节,其作用主要是限制网络包的大小,如果 IP 层有一个数
据报要传,而且网络包的⻓度比链路层的 MTU 还大,那么 IP 层就 需要进行分片,即把数据报分
成若干片,这样每一片就都小于 MTU 。事实上,每个网络的链路层 MTU 可能会不一样,所以你
可能需要调大或者调小 MTU 的数值。
第三,网口的 IP 地址 、子网掩码、MAC 地址 、网关地址 。这些信息必须要配置正确,网络功能才
能正常工作。
第四,网络包收发的统计信息。通常有网络收发的字节数、包数、错误数以及丢包情况的信息,
如果 TX (发送) 和 RX (接收) 部分中 errors 、dropped 、overruns 、carrier 以及 collisions
等指标不为 0 时,则说明网络发送或者接收出问题了,这些出错统计信息的指标意义如下:
errors 表示发生错误的数据包数,比如校验错误、帧同步错误等;
dropped 表示丢弃的数据包数,即数据包已经收到了 Ring Buffer (这个缓冲区是在内核内存
中,更具体一点是在网卡驱动程序里),但因为系统内存不足等原因而发生的丢包;
overruns 表示超限数据包数,即网络接收/发送速 度过快,导致 Ring Buffer 中的数据包来不及
处理,而导致的丢包,因为过多的数据包挤压在 Ring Buffer ,这样 Ring Buffer 很容易就溢出
了;
carrier 表示发生 carrirer 错误的数据包数,比如双工模式不匹配、物理电缆出现问题等;
collisions 表示冲突、碰撞数据包数;
ifconfig 和 ip 命令只显示的是网口的配置以及收发数据包的统计信息,而看不到协议栈里的
信息,那接下来就来看看 如何查看协议栈里的信息。
socket 信息如何查看?
我们可以使 用 netstat 或者 ss ,这两个 命令查看 socket 、网络协议栈、网口以及路由表的信
息。
虽然 netstat 与 ss 命令查看的信息都差不多,但是如果在生产环境中要查看这类信息的时
候,尽量不要使用 netstat 命令,因为它的性能不好,在系统比较繁忙的情况下,如果频繁使用
netstat 命令则会对性能的开销雪上加霜,所以更推荐你使 用性能更好的 ss 命令。
从下 面这张图,你可以看到这两个 命令的输出内容:

可以发现,输出的内容都差不多, 比如都包含了 socket 的状态(State )、接收队列(Recv-Q )、发
送队列(Send-Q )、本地地址 (Local Address )、远端地址 (Foreign Address )、进程 PID 和进程名
称(PID/Program name )等。
接收队列(Recv-Q )和发送队列(Send-Q )比较特殊,在不同的 socket 状态。它们表示的含义是
不同的。
当 socket 状态处于 Established 时:
Recv-Q 表示 socket 缓冲区中还没有被应用程序读取的字节数;
Send-Q 表示 socket 缓冲区中还没有被远端主机确认的字节数;
而当 socket 状态处于 Listen 时:
Recv-Q 表示全连接队列的⻓度;
Send-Q 表示全连接队列的最大⻓度;
在 TCP 三次握手过程中,当服务器收到客⼾端的 SYN 包后,内核会把该连接存储到半连接队列,
然后再向客⼾端发送 SYN+ACK 包,接着客⼾端会返回 ACK ,服务端收到第三次握手的 ACK 后,
内核会把连接从半连接队列移除,然后创建新的完全的连接,并将其增加到 全连接队列 ,等待进

程调用 accept() 函数时把连接取出来。
也就说,全连接队列指的是服务器与客⼾端完了 TCP 三次握手后,还没有被 accept() 系统调用取走连接的队列。
那对于协议栈的统计信息,依然还是使用 netstat 或 ss ,它们查看统计信息的命令如下:

ss 命令输出的统计信息相比 netsat 比较少, ss 只显示已经连接(estab )、关闭(closed )、
孤儿(orphaned ) socket 等简 要统计。
而 netstat 则有更 详细的网络协议栈信息,比如上面显示了 TCP 协议的主动连接(active connections openings )、被动连接(passive connection openings )、失败重试(failed connection attempts )、发送(segments send out )和接收(segments received )的分段数量等各种信息。
网络吞吐 率和 PPS 如何查看?
可以使 用 sar 命令当前网络的吞吐 率和 PPS ,用法是给 sar 增加 -n 参数就可以查看网络的
统计信息,比如
sar -n DEV ,显示网口的统计数据;
sar -n EDEV ,显示关于网络错误的统计数据;
sar -n TCP ,显示 TCP 的统计数据
比如,我通过 sar 命令获取了网口的统计信息:

它们的含义:
rxpck/s 和 txpck/s 分别 是接收和发送的 PPS ,单位为包 / 秒。
rxkB/s 和 txkB/s 分别 是接收和发送的吞吐 率,单位是 KB/ 秒。
rxcmp/s 和 txcmp/s 分别 是接收和发送的压缩数据包数,单位是包 / 秒。
对于带宽,我们可以使 用 ethtool 命令来查 询,它的单位通常是 Gb/s 或者 Mb/s ,不过注意
这里小写字⺟ b ,表示比特而不是字节。我们通常提到的千兆网卡、万兆网卡等,单位也都是
比特(bit )。如下你可以看到, eth0 网卡就是一个千兆网卡:
$ ethtool eth0 | grep Speed
Speed: 1000Mb/s
连通性和延时如何查看?
要测试本机 与远程主机的连通性和延时,通常是使用 ping 命令,它是基于 ICMP 协议的,工作
在网络层。
比如,如果要测试本机 到 192.168.12.20 IP 地址 的连通性和延时:

显示的内容主要包含 icmp_seq (ICMP 序列号)、 TTL (生存时间,或者跳数)以及 time
(往返延时),而且最后会汇总本次测试的情况,如果网络没有丢包, packet loss 的百 分比就是
0。
