一、上节回顾

上一节,我带你学习了 Linux 网络的基础原理。简单回顾一下,Linux 网络根据 TCP/IP模型,构建其网络协议栈。TCP/IP 模型由应用层、传输层、网络层、网络接口层等四层组
成,这也是 Linux 网络栈最核心的构成部分。

应用程序通过套接字接口发送数据包时,先要在网络协议栈中从上到下逐层处理,然后才最终送到网卡发送出去;而接收数据包时,也要先经过网络栈从下到上的逐层处理,最后送到应用程序。

了解 Linux 网络的基本原理和收发流程后,你肯定迫不及待想知道,如何去观察网络的性能情况。具体而言,哪些指标可以用来衡量 Linux 的网络性能呢?

二、性能指标

实际上,我们通常用带宽、吞吐量、延时、PPS(Packet Per Second)等指标衡量网络的性能。

带宽:表示链路的最大传输速率,单位通常为 b/s (比特 / 秒)。

吞吐量:表示单位时间内成功传输的数据量,单位通常为 b/s(比特 / 秒)或者B/s(字节 / 秒)。吞吐量受带宽限制,而吞吐量 / 带宽,也就是该网络的使用率。

延时:表示从网络请求发出后,一直到收到远端响应,所需要的时间延迟。在不同场景中,这一指标可能会有不同含义。比如,它可以表示,建立连接需要的时间(比如 TCP
   握手延时),或一个数据包往返所需的时间(比如 RTT)。

PPS:是 Packet Per Second(包 / 秒)的缩写,表示以网络包为单位的传输速率。PPS 通常用来评估网络的转发能力,比如硬件交换机,通常可以达到线性转发(即 PPS
      可以达到或者接近理论最大值)。而基于 Linux 服务器的转发,则容易受网络包大小的影响。

除了这些指标,网络的可用性(网络能否正常通信)、并发连接数(TCP 连接数量)、丢包率(丢包百分比)、重传率(重新传输的网络包比例)等也是常用的性能指标。

接下来,请你打开一个终端,SSH 登录到服务器上,然后跟我一起来探索、观测这些性能指标。

三、网络配置

分析网络问题的第一步,通常是查看网络接口的配置和状态。你可以使用 ifconfig 或者 ip命令,来查看网络的配置。我个人更推荐使用 ip 工具,因为它提供了更丰富的功能和更易
用的接口。

以网络接口 eth0 为例,你可以运行下面的两个命令,查看它的配置和状态:

root@luoahong:~# ifconfig ens34
ens34: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.118.74 netmask 255.255.255.0 broadcast 192.168.118.255
inet6 fe80::20c:29ff:fe03:d3a7 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:03:d3:a7 txqueuelen 1000 (Ethernet)
RX packets 460768 bytes 587423814 (587.4 MB)
RX errors 0 dropped 100 overruns 0 frame 0
TX packets 122590 bytes 29027840 (29.0 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 root@luoahong:~# ip -s addr show dev ens34
2: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 00:0c:29:03:d3:a7 brd ff:ff:ff:ff:ff:ff
inet 192.168.118.74/24 brd 192.168.118.255 scope global dynamic ens34
valid_lft 66745sec preferred_lft 66745sec
inet6 fe80::20c:29ff:fe03:d3a7/64 scope link
valid_lft forever preferred_lft forever
RX: bytes packets errors dropped overrun mcast
587440742 460987 0 100 0 0
TX: bytes packets errors dropped carrier collsns
29036492 122677 0 0 0 0

你可以看到,ifconfig 和 ip 命令输出的指标基本相同,只是显示格式略微不同。比如,它们都包括了网络接口的状态标志、MTU 大小、IP、子网、MAC 地址以及网络包收发的统计信息。

这些具体指标的含义,在文档中都有详细的说明,不过,这里有几个跟网络性能密切相关的指标,需要你特别关注一下。

第一,网络接口的状态标志。ifconfig 输出中的 RUNNING ,或 ip 输出中的LOWER_UP ,都表示物理网络是连通的,即网卡已经连接到了交换机或者路由器中。如
          果你看不到它们,通常表示网线被拔掉了。
第二,MTU 的大小。MTU 默认大小是 1500,根据网络架构的不同(比如是否使用了VXLAN 等叠加网络),你可能需要调大或者调小 MTU 的数值。

第三,网络接口的 IP 地址、子网以及 MAC 地址。这些都是保障网络功能正常工作所必需的,你需要确保配置正确。
第四,网络收发的字节数、包数、错误数以及丢包情况,特别是 TX 和 RX 部分的errors、dropped、overruns、carrier 以及 collisions 等指标不为 0 时,通常表示出现
    了网络 I/O 问题。其中:

errors 表示发生错误的数据包数,比如校验错误、帧同步错误等;
dropped 表示丢弃的数据包数,即数据包已经收到了 Ring Buffer,但因为内存不足等原因丢包;
overruns 表示超限数据包数,即网络 I/O 速度过快,导致 Ring Buffer 中的数据包来不及处理(队列满)而导致的丢包;
carrier 表示发生 carrirer 错误的数据包数,比如双工模式不匹配、物理电缆出现问题等;
collisions 表示碰撞数据包数。

四、套接字信息

ifconfig 和 ip 只显示了网络接口收发数据包的统计信息,但在实际的性能问题中,网络协议栈中的统计信息,我们也必须关注。你可以用 netstat 或者 ss ,来查看套接字、网络
栈、网络接口以及路由表的信息。

我个人更推荐,使用 ss 来查询网络的连接信息,因为它比 netstat 提供了更好的性能(速度更快)。比如,你可以执行下面的命令,查询套接字信息:

root@luoahong:~# netstat -nlp|head -n 3
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Programname
tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 840/systemd-resolve
root@luoahong:~# ss -ltnp|head -n 3
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=840,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1215,fd=3))

netstat 和 ss 的输出也是类似的,都展示了套接字的状态、接收队列、发送队列、本地地址、远端地址、进程 PID 和进程名称等。

其中,接收队列(Recv-Q)和发送队列(Send-Q)需要你特别关注,它们通常应该是0。当你发现它们不是 0 时,说明有网络包的堆积发生。当然还要注意,在不同套接字状态下,它们的含义不同。

1、当套接字处于连接状态(Established)时,

Recv-Q 表示套接字缓冲还没有被应用程序取走的字节数(即接收队列长度)。而 Send-Q 表示还没有被远端主机确认的字节数(即发送队列长度)。

2、当套接字处于监听状态(Listening)时,

Recv-Q 表示 syn backlog 的当前值。而 Send-Q 表示最大的 syn backlog 值。

而 syn backlog 是 TCP 协议栈中的半连接队列长度,相应的也有一个全连接队列(accept queue),它们都是维护 TCP 状态的重要机制。

3、什么是半路连接?

顾名思义,所谓半连接,就是还没有完成 TCP 三次握手的连接,连接只进行了一半,而服务器收到了客户端的 SYN 包后,就会把这个连接放到半连接队列中,然后再向客户端发送
SYN+ACK 包。

4、什么是全路连接?

而全连接,则是指服务器收到了客户端的 ACK,完成了 TCP 三次握手,然后就会把这个连接挪到全连接队列中。这些全连接中的套接字,还需要再被 accept() 系统调用取走,这
样,服务器就可以开始真正处理客户端的请求了。

五、协议栈统计信息

类似的,使用 netstat 或 ss ,也可以查看协议栈的信息:

root@luoahong:~# netstat -s
Ip:
Forwarding: 1
207047 total packets received
2 with invalid addresses
216 forwarded
0 incoming packets discarded
206829 incoming packets delivered
119198 requests sent out
20 outgoing packets dropped
Icmp:
43 ICMP messages received
0 input ICMP message failed
ICMP input histogram:
destination unreachable: 40
echo requests: 1
echo replies: 2
117 ICMP messages sent
0 ICMP messages failed
ICMP output histogram:
destination unreachable: 114
echo requests: 2
echo replies: 1
IcmpMsg:
InType0: 2
InType3: 40
InType8: 1
OutType0: 1
OutType3: 114
OutType8: 2
Tcp:
415 active connection openings
3 passive connection openings
0 failed connection attempts
7 connection resets received
1 connections established
196251 segments received
124187 segments sent out
52 segments retransmitted
0 bad segments received
226 resets sent
Udp:
1042 packets received
139 packets to unknown port received
0 packet receive errors
1084 packets sent
0 receive buffer errors
0 send buffer errors
IgnoredMulti: 9264
UdpLite:
TcpExt:
5 TCP sockets finished time wait in fast timer
149 delayed acks sent
9 delayed acks further delayed because of locked socket
Quick ack mode was activated 3 times
161413 packet headers predicted
12736 acknowledgments not containing data payload received
2975 predicted acknowledgments
TCPTimeouts: 10
TCPLossProbes: 13
TCPLossProbeRecovery: 2
TCPDSACKOldSent: 3
TCPDSACKRecv: 9
6 connections reset due to unexpected data
7 connections reset due to early user close
TCPDSACKIgnoredNoUndo: 2
TCPRcvCoalesce: 91930
TCPOFOQueue: 10697
TCPAutoCorking: 1357
TCPSynRetrans: 40
TCPOrigDataSent: 27150
TCPHystartTrainDetect: 1
TCPHystartTrainCwnd: 16
TCPKeepAlive: 4
IpExt:
InBcastPkts: 9264
InOctets: 580667049
OutOctets: 23375191
InBcastOctets: 1053751
InNoECTPkts: 424052
root@luoahong:~# ss -s
Total: 556 (kernel 2442)
TCP: 4 (estab 1, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0 Transport Total IP IPv6
* 2442 - -
RAW 1 0 1
UDP 2 2 0
TCP 4 3 1
INET 7 5 2
FRAG 0 0 0

这些协议栈的统计信息都很直观。ss 只显示已经连接、关闭、孤儿套接字等简要统计,而netstat 则提供的是更详细的网络协议栈信息。

比如,上面 netstat 的输出示例,就展示了 TCP 协议的主动连接、被动连接、失败重试、发送和接收的分段数量等各种信息。

六、网络吞吐和 PPS

接下来,我们再来看看,如何查看系统当前的网络吞吐量和 PPS。在这里,我推荐使用我们的老朋友 sar,在前面的 CPU、内存和 I/O 模块中,我们已经多次用到它。

给 sar 增加 -n 参数就可以查看网络的统计信息,比如网络接口(DEV)、网络接口错误(EDEV)、TCP、UDP、ICMP 等等。执行下面的命令,你就可以得到网络接口统计信息:

root@luoahong:~# sar -n DEV 1
Linux 4.15.0-48-generic (luoahong) 09/03/2019 _x86_64_ (2 CPU)
04:51:51 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
04:51:52 PM ens34 4.95 0.99 0.52 0.80 0.00 0.00 0.00 0.00
04:51:52 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
04:51:52 PM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 04:51:52 PM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
04:51:53 PM ens34 3.00 1.00 0.18 0.81 0.00 0.00 0.00 0.00
04:51:53 PM lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
04:51:53 PM docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
^C Average: IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
Average: ens34 3.66 1.26 0.31 0.79 0.00 0.00 0.00 0.00
Average: lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: docker0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

这儿输出的指标比较多,我来简单解释下它们的含义。

1、rxpck/s 和 txpck/s 分别是接收和发送的 PPS,单位为包 / 秒。
2、rxkB/s 和 txkB/s 分别是接收和发送的吞吐量,单位是 KB/ 秒。
3、rxcmp/s 和 txcmp/s 分别是接收和发送的压缩数据包数,单位是包 / 秒。
4、%ifutil 是网络接口的使用率,即半双工模式下为 (rxkB/s+txkB/s)/Bandwidth,而全双工模式下为 max(rxkB/s, txkB/s)/Bandwidth

其中,Bandwidth 可以用 ethtool 来查询,它的单位通常是 Gb/s 或者 Mb/s,不过注意这里小写字母 b ,表示比特而不是字节。我们通常提到的千兆网卡、万兆网卡等,单位也
都是比特。如下你可以看到,我的 eth0 网卡就是一个千兆网卡:

root@luoahong:~#ethtool eth0 | grep Speed
Speed: 1000Mb/s

七、连通性和延时

最后,我们通常使用 ping ,来测试远程主机的连通性和延时,而这基于 ICMP 协议。比如,执行下面的命令,你就可以测试本机到 114.114.114.114 这个 IP 地址的连通性和延时:

root@luoahong:~# ping -c3 114.114.114.114
PING 114.114.114.114 (114.114.114.114) 56(84) bytes of data.
64 bytes from 114.114.114.114: icmp_seq=1 ttl=70 time=22.7 ms
64 bytes from 114.114.114.114: icmp_seq=2 ttl=76 time=25.1 ms
64 bytes from 114.114.114.114: icmp_seq=3 ttl=89 time=23.2 ms --- 114.114.114.114 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2005ms
rtt min/avg/max/mdev = 22.724/23.722/25.186/1.057 ms

ping 的输出,可以分为两部分。

第一部分,是每个 ICMP 请求的信息,包括 ICMP 序列号(icmp_seq)、TTL(生存时间,或者跳数)以及往返延时。

第二部分,则是三次 ICMP 请求的汇总。

比如上面的示例显示,发送了 3 个网络包,并且接收到 3 个响应,没有丢包发生,这说明测试主机到 114.114.114.114 是连通的;平均往返延时(RTT)是 22.7ms,也就是从发
送 ICMP 开始,到接收到 114.114.114.114 回复的确认,总共经历 22.7ms。

Linux性能优化实战学习笔记:第三十四讲的更多相关文章

  1. Linux性能优化实战学习笔记:第二十四讲

    一.磁盘 1.机械磁盘 2.固态磁盘 3.相同磁盘随机I/O比连续I/O慢很多 4.最小单位 5.接口 6.RAID陈列卡 7.网路存储 二.通用块层 1.概念 2.第一功能 3.第二功能 4.I/O ...

  2. Linux性能优化实战学习笔记:第十八讲

    一.内存的分配和回收 1.管理内存的过程中,也很容易发生各种各样的“事故”, 对应用程序来说,动态内存的分配和回收,是既核心又复杂的一的一个逻辑功能模块.管理内存的过程中,也很容易发生各种各样的“事故 ...

  3. Linux性能优化实战学习笔记:第十二讲

    一.性能优化方法论 不可中断进程案例 二.怎么评估性能优化的效果? 1.评估思路 2.几个为什么 1.为什么要选择不同维度的指标? 应用程序和系统资源是相辅相成的关系 2.性能优化的最终目的和结果? ...

  4. Linux性能优化实战学习笔记:第十六讲

    一.free数据的来源 1.碰到看不明白的指标时该怎么办吗? 不懂就去查手册.用 man 命令查询 free 的文档.就可以找到对应指标的详细说明.比如,我们执行 man fre... 2.free数 ...

  5. Linux性能优化实战学习笔记:第二十八讲

    一.案例环境描述 1.环境准备 2CPU,4GB内存 预先安装docker sysstat工具 apt install docker.io sysstat nake git 案例总共由三个容器组成: ...

  6. Linux性能优化实战学习笔记:第二十六讲

    一.案例环境描述 1.环境准备 2CPU,4GB内存 预先安装docker sysstat工具 2.温馨提示 案例中 Python 应用的核心逻辑比较简单,你可能一眼就能看出问题,但实际生产环境中的源 ...

  7. Linux性能优化实战学习笔记:第五十七讲

    一.上节回顾 上一节,我带你一起梳理了常见的性能优化思路,先简单回顾一下.我们可以从系统和应用程序两个角度,来进行性能优化. 从系统的角度来说,主要是对 CPU.内存.网络.磁盘 I/O 以及内核软件 ...

  8. Linux性能优化实战学习笔记:第五十一讲

    一.上节回顾 上一节,我带你一起学习了常见的动态追踪方法.所谓动态追踪,就是在系统或者应用程序正常运行的时候,通过内核中提供的探针,来动态追踪它们的行为,从而辅助排查出性能问题的瓶颈. 使用动态追踪, ...

  9. Linux性能优化实战学习笔记:第十讲

    一.坏境准备 1.拓扑图 2.安装包 在第9节的基础上 在VM2上安装hping3依奈包 wget http://www.tcpdump.org/release/libpcap-1.9.0.tar.g ...

  10. Linux性能优化实战学习笔记:第十三讲

    问题1:性能工具版本太低,导致指标不全 解决方案1: 这是使用 CentOS 的同学普遍碰到的问题.在文章中,我的pidstat 输出里有一个 %wait 指标,代表进程等待 CPU 的时间百分比, ...

随机推荐

  1. nginx二级域名反向代理

    nginx二级域名反向代理 添加两个开发测试的域名 test.xxx.com :8088 testmobile.xxx.com: 8089 内网地址:127.0.0.1 外网地址:127.0.0.1 ...

  2. 第八周论文学习03 An Efficient Tree-based Power Saving Scheme for Wireless Sensor Networks with Mobile Sink

    来源:IEEE Sensors Journal Year: 2016, Volume: 16, Issue: 20 Pages: 7545 - 7557, DOI: 10.1109/JSEN.2016 ...

  3. NXP官方ddr_stress_tester工具使用

    1.前言 NXP官方提供了一个DDR初始化工具,名称为ddr_stress_tester,该工具具有以下特点: 该工具能通过USB OTG接口与目标板进行连接,通过USB OTG接口完成DDR的初始化 ...

  4. 基于MicroPython:TPYBoard心率监测器

    转载请注明文章来源,更多教程可自助参考docs.tpyboard.com,QQ技术交流群:157816561,公众号:MicroPython玩家汇 一.前言 这几年智能穿戴设备大火,尤其是手环类,从A ...

  5. windows 安装gitea

    gitea 地址https://github.com/go-gitea/gitea windows 安装 

  6. 2019-11-29-dotnet-core-使用-GBK-编码

    原文:2019-11-29-dotnet-core-使用-GBK-编码 title author date CreateTime categories dotnet core 使用 GBK 编码 li ...

  7. webform的原生操作图片预览和上传

    1.使用input标签进行图片操作,input的标签有一个accept属性,accept 属性只能与 <input type="file"> 配合使用.它规定能够通过文 ...

  8. Python - 数字 - 第六天

    Python 数字(Number) Python 数字数据类型用于存储数值. 数据类型是不允许改变的,这就意味着如果改变数字数据类型的值,将重新分配内存空间. 以下实例在变量赋值时 Number 对象 ...

  9. 2019前端UI框架排行榜

    一.Mint UI 流行指数:★★★★ Mint UI是 饿了么团队开发基于 Vue.js 的移动端UI框架,它包含丰富的 CSS 和 JS 组件,能够满足日常的移动端开发需要. 官网:https:/ ...

  10. string 字符串 的一些使用方法

    Java语言中,把字符串作为对象来处理,类String就可以用来表示字符串(类名首字母都是大写的). 字符串常量是用双引号括住的一串字符. 例如:"Hello World" Str ...