前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >性能之网络篇

性能之网络篇

作者头像
灰子学技术
发布2022-06-25 09:19:30
6730
发布2022-06-25 09:19:30
举报
文章被收录于专栏:灰子学技术灰子学技术

网络通讯的链路为:机器A-----》路由器----〉机器B

如果我们站在本机机器作为参考物的话,应该拆分成下面三个阶段: 1.消息入口流量部分的处理流程

2.流量在本机上面的处理流程 3.流量出口流量部分的处理流程

在上面的这三个阶段,分别涉及到了不同的基础知识、工具和命令来进行诊断,笔者本篇文章按照下面的内容来整理: 1.基础知识 2.常用工具和命令 3.测试工具

一、基础知识

衡量网络性能的主要指标为:

带宽:表示链路的最大传输速率,单位是 b/s(比特 / 秒),常用的带宽有 1000M、10G、40G、100G 等。

吞吐量:表示没有丢包时的最大数据传输速率,单位通常为 b/s (比特 / 秒)或者 B/s(字节 / 秒),吞吐量受带宽的限制,吞吐量 / 带宽也就是该网络链路的使用率。

延时:表示从网络请求发出后,一直到收到远端响应,所需要的时间延迟,表示建立连接需要的时间(比如 TCP 握手延时),或者一个数据包往返所需时间(比如 RTT)。

通常,我们更常用的是双向的往返通信延迟,比如 ping 测试的结果,就是往返延时 RTT(Round-Trip Time)。除了网络延迟外,另一个常用的指标是应用程序延迟,它是指,从应用程序接收到请求,再到发回响应,全程所用的时间。应用程序延迟也指的是往返延迟,是网络数据传输时间加上数据处理时间的和。

PPS:Packet Per Second(包 / 秒)的缩写,表示以网络包为单位的传输速率。PPS 通常用来评估网络的转发能力,而基于 Linux 服务器的转发,很容易受到网络包大小的影响(交换机通常不会受到太大影响,即交换机可以线性转发)。PPS,是以网络包为单位的网络传输速率,通常用在需要大量转发的场景中。对 TCP 或者 Web 服务来说,更多会用并发连接数和每秒请求数(QPS,Query per Second)等指标,它们更能反应实际应用程序的性能。

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

备注:网络接口层和网络层,它们主要负责网络包的封装、寻址、路由以及发送和接收。在这两个网络协议层中,每秒可处理的网络包数 PPS,就是最重要的性能指标,特别是 64B 小包的处理能力,值得我们特别关注。)

1.本机内部的流量处理知识整理:

Linux 内核中的网络栈,类似于 TCP/IP 的四层结构,如下所示:

对于操作系统中的数据包收发流程,如下所示:

2.本机入口和出口流量的处理知识点整理:

1)对于机器的入口流量来说,主要涉及到的知识便是C10K、C1000K、C10M的场景处理。

C10K 、C1000K、 C10M的首字母 C 是 Client 的缩写,C10K 是单机同时处理 1 万个请求(并发连接 1 万)的问题,C1000K 是单机支持处理 100 万个请求(并发连接 100 万)的问题,C10M是1000万个请求(并发连接1000万)的问题。 1>I/O 模型的优化,特别是Linux 2.6 中引入的 epoll完美解决了 C10K 的问题。 I/O 模型相关知识参看笔者整理的下面几篇文章: https://mp.weixin.qq.com/s/_EL5gl2xfsLVUIyFyd1tyg https://mp.weixin.qq.com/s/Xi2tX3GiZfSQhod1nQmy2A

https://mp.weixin.qq.com/s/fQoHegyRO0MGnwp9ADYmSg

https://mp.weixin.qq.com/s/yB_GimOPl6o4VB85Wlh1dQ https://mp.weixin.qq.com/s/SMe8Kn4LA1aR0OrWN6I5Ww

2>从 C10K 到 C100K,我们只需要增加系统的物理资源,就可以满足要求。 3>从 C100K 到 C1000K ,光增加物理资源就不够了。这时,就要对系统的软硬件进行统一优化,从硬件的中断处理,到网络协议栈的文件描述符数量、连接状态跟踪、缓存队列,再到应用程序的工作模型等的整个网络链路,都需要深入优化。4>要实现 C10M,就不是增加物理资源、调优内核和应用程序可以解决的问题了,这时内核中冗长的网络协议栈就成了最大的负担。需要用 XDP 方式,在内核协议栈之前,先处理网络包;或基于 DPDK ,直接跳过网络协议栈,在用户空间通过轮询的方式处理。

DPDK:是用户态网络的标准,它跳过内核协议栈,直接由用户态进程通过轮询的方式,来处理网络接收。对于C10M场景,基本上每时每刻都有新的网络包需要处理,轮询的优势就很明显了。

代码语言:javascript
复制
1. 在 PPS 非常高的场景中,查询时间比实际工作时间少了很多,绝大部分时间都在处理网络包;
2. 跳过内核协议栈后,就省去了繁杂的硬中断、软中断再到 Linux 网络协议栈逐层处理的过程,
应用程序可以针对应用的实际场景,有针对性地优化网络包的处理逻辑,而不需要关注所有的细节。
3. DPDK 还通过大页、CPU 绑定、内存对齐、流水线并发等多种机制,优化网络包的处理效率。

备注:DPDK 是目前最主流的高性能网络方案,不过,这需要能支持 DPDK 的网卡配合使用。)

XDP(eXpress Data Path):则是 Linux 内核提供的一种高性能网络数据路径,它允许网络包,在进入内核协议栈之前,就进行处理,也可以带来更高的性能,XDP 底层都是基于 Linux 内核的 eBPF 机制实现的。

备注:XDP 对内核的要求比较高,需要的是 Linux 4.8 以上版本,并且它也不提供缓存队列,基于 XDP 的应用程序通常是专用的网络应用,常见的有 IDS(入侵检测系统)、DDoS 防御、 cilium 容器网络插件等。)

2) iptables 与 NAT:

NAT 技术可以重写 IP 数据包的源 IP 或者目的 IP,被普遍地用来解决公网 IP 地址短缺的问题。它的主要原理就是,网络中的多台主机,通过共享同一个公网 IP 地址,来访问外网资源,同时,由于 NAT 屏蔽了内网网络,自然也就为局域网中的机器提供了安全隔离。

NAT 的主要目的,是实现地址转换,根据实现方式的不同,NAT 可以分为三类:

代码语言:javascript
复制
静态 NAT,即内网 IP 与公网 IP 是一对一的永久映射关系;
动态 NAT,即内网 IP 从公网 IP 池中,动态选择一个进行映射;
网络地址端口转换 NAPT(Network Address and Port Translation),即把内网 IP 映射到公网 IP 的不同端口上,让多个内网 IP 可以共享同一个公网 IP 地址。

iptables: Linux 内核提供的 Netfilter 框架,允许对网络数据包进行修改(比如 NAT)和过滤(比如防火墙)。在这个基础上,iptables、ip6tables、ebtables 等工具,又提供了更易用的命令行接口,以便系统管理员配置和管理 NAT、防火墙的规则,其中,iptables 就是最常用的一种配置工具。 iptables详细知识点可以参考笔者的另外一篇文章:

https://mp.weixin.qq.com/s/DiW9TNuhW75oPLR9WffzkA

3. 非本机相关的网络知识: DNS(Domain Name System),即域名系统,是互联网中最基础的一项服务,主要提供域名和 IP 地址之间映射关系的查询服务。

详细知识点可以参考笔者整理的另外一篇文章: https://mp.weixin.qq.com/s/eLlGL55UoUt2HmhDWD43Sg

二、工具和命令介绍:

  1. 查看网络配置 ifconfig、ip
代码语言:javascript
复制
# RUNNING,LOWER_UP: 表示物理网络是连通的
# RX:receive,表示的是接收数据,从开启到现在接收封包的情况,是下行流量(Downlink)
# TX:Transmit,表示的是发送数据,从开启到现在发送封包的情况,是上行流量(Uplink)。
# errors 表示发生错误的数据包数,比如校验错误、帧同步错误等;
# dropped 表示丢弃的数据包数,即数据包已经收到了 Ring Buffer,但因为内存不足等原因丢包;
# overruns 表示超限数据包数,即网络 I/O 速度过快,导致 Ring Buffer 中的数据包来不及处理(队列满)而导致的丢包;
# carrier 表示发生 carrirer 错误的数据包数,比如双工模式不匹配、物理电缆出现问题等;
# collisions 表示碰撞数据包数。
$ ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
      inet 10.240.0.30 netmask 255.240.0.0 broadcast 10.255.255.255
      inet6 fe80::20d:3aff:fe07:cf2a prefixlen 64 scopeid 0x20<link>
      ether 78:0d:3a:07:cf:3a txqueuelen 1000 (Ethernet)
      RX packets 40809142 bytes 9542369803 (9.5 GB)
      RX errors 0 dropped 0 overruns 0 frame 0
      TX packets 32637401 bytes 4815573306 (4.8 GB)
      TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

$ ip -s addr show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
  link/ether 78:0d:3a:07:cf:3a brd ff:ff:ff:ff:ff:ff
  inet 10.240.0.30/12 brd 10.255.255.255 scope global eth0
      valid_lft forever preferred_lft forever
  inet6 fe80::20d:3aff:fe07:cf2a/64 scope link
      valid_lft forever preferred_lft forever
  RX: bytes packets errors dropped overrun mcast
   9542432350 40809397 0       0       0       193
  TX: bytes packets errors dropped carrier collsns
   4815625265 32637658 0       0       0       0

2. 查看套接字、网络栈、网络接口以及路由表的信息 netstat、ss

1)当套接字处于连接状态(Established):

Recv-Q 表示套接字缓冲还没有被应用程序取走的字节数(即接收队列长度)。

Send-Q 表示还没有被远端主机确认的字节数(即发送队列长度)。

2)当套接字处于监听状态(Listening): Recv-Q 表示全连接队列的长度。 Send-Q 表示全连接队列的最大长度。

代码语言:javascript
复制
# head -n 3 表示只显示前面3行
# -l 表示只显示监听套接字
# -n 表示显示数字地址和端口(而不是名字)
# -p 表示显示进程信息
$ netstat -nlp | head -n 3
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      840/systemd-resolve

# -l 表示只显示监听套接字
# -t 表示只显示 TCP 套接字
# -n 表示显示数字地址和端口(而不是名字)
# -p 表示显示进程信息
$ 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=1459,fd=3))
           
 # 协议栈统计信息
$ netstat -s
#主动连接、被动连接、失败重试、发送和接收的分段数量等各种信息
...
Tcp:
    3244906 active connection openings
    23143 passive connection openings
    115732 failed connection attempts
    2964 connection resets received
    1 connections established
    13025010 segments received
    17606946 segments sent out
    44438 segments retransmitted
    42 bad segments received
    5315 resets sent
    InCsumErrors: 42
...

$ ss -s
Total: 186 (kernel 1446)
TCP:   4 (estab 1, closed 0, orphaned 0, synrecv 0, timewait 0/0), ports 0

Transport Total     IP        IPv6
*    1446      -         -
RAW    2         1         1
UDP    2         2         0
TCP    4         3         1
...

3. 查看系统当前的网络吞吐量和 PPS:sar

代码语言:javascript
复制
# 数字1表示每隔1秒输出一组数据
$ sar -n DEV 1 // -n 参数就可以查看网络的统计信息,DEV是接口
#rxpck/s 和 txpck/s 分别是接收和发送的 PPS,单位为包 / 秒。
# rxkB/s 和 txkB/s 分别是接收和发送的吞吐量,单位是 KB/ 秒。
# rxcmp/s 和 txcmp/s 分别是接收和发送的压缩数据包数,单位是包 / 秒。
# %ifutil 是网络接口的使用率,即半双工模式下为 (rxkB/s+txkB/s)/Bandwidth,而全双工模式下为 max(rxkB/s, txkB/s)/Bandwidth。
Linux 4.15.0-1035 (ubuntu)   01/06/19   _x86_64_  (2 CPU)

13:21:40        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
13:21:41         eth0     18.00     20.00      5.79      4.25      0.00      0.00      0.00      0.00
13:21:41      docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
13:21:41           lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

Bandwidth 可以用 ethtool 来查询,它的单位通常是 Gb/s 或者 Mb/s,这里小写字母 b ,表示比特而不是字节。

代码语言:javascript
复制
$ ethtool eth0 | grep Speed
  Speed: 1000Mb/s

4.连通性和延迟 ping

代码语言:javascript
复制
# -c3表示发送三次ICMP包后停止
# 第一部分,是每个 ICMP 请求的信息,包括 ICMP 序列号(icmp_seq)、TTL(生存时间,或者跳数)以及往返延时。
$ 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=54 time=244 ms
64 bytes from 114.114.114.114: icmp_seq=2 ttl=47 time=244 ms
64 bytes from 114.114.114.114: icmp_seq=3 ttl=67 time=244 ms
# 第二部分,则是三次 ICMP 请求的汇总。
--- 114.114.114.114 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 244.023/244.070/244.105/0.034 ms

5.抓包工具tcpdump

安装:

代码语言:javascript
复制
# Ubuntu
apt-get install tcpdump wireshark
# CentOS
yum install -y tcpdump wireshark

使用介绍:

代码语言:javascript
复制
# -nn ,表示不解析抓包中的域名(即不反向解析)、协议以及端口号。
# udp port 53 ,表示只显示 UDP 协议的端口号(包括源端口和目的端口)为 53 的包。
# host 35.190.27.188 ,表示只显示 IP 地址(包括源地址和目的地址)为 35.190.27.188 的包。
# 这两个过滤条件中间的“ or ”,表示或的关系,也就是说,只要满足上面两个条件中的任一个,就可以展示出来。
# -w ping.pcap 表示输出到本地的ping.pcap存储起来
$ tcpdump -nn udp port 53 or host 35.190.27.188 -w ping.pcap

下载到本地机器,使用wireshark进行分析

代码语言:javascript
复制
$ scp host-ip/path/ping.pcap .

6.路由相关工具:mtr、route、traceroute

代码语言:javascript
复制
# --tcp表示使用TCP协议,-p表示端口号,-n表示不对结果中的IP地址执行反向域名解析
$ traceroute --tcp -p 80 -n baidu.com
traceroute to baidu.com (123.125.115.110), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
 4  * * *
 5  * * *
 6  * * *
 7  * * *
 8  * * *
 9  * * *
10  * * *
11  * * *
12  * * *
13  * * *
14  123.125.115.110  20.684 ms *  20.798 ms

三、压测工具介绍

0.转发性能:hping3

网络接口层和网络层,它们主要负责网络包的封装、寻址、路由以及发送和接收,在这两个网络协议层中,每秒可处理的网络包数 PPS,就是最重要的性能指标。

hping3 可以作为一个测试网络包处理能力的性能工具。

代码语言:javascript
复制
# -S参数表示设置TCP协议的SYN(同步序列号),-p表示目的端口为80
# -i u10表示每隔10微秒发送一个网络帧
$ hping3 -S -p 80 -i u10 192.168.0.30

(备注:Linux 内核自带的高性能网络测试工具 pktgen

代码语言:javascript
复制
# -c表示发送3次请求,-S表示设置TCP SYN,-p表示端口号为80
$ hping3 -c 3 -S -p 80 baidu.com
HPING baidu.com (eth0 123.125.115.110): S set, 40 headers + 0 data bytes
len=46 ip=123.125.115.110 ttl=51 id=47908 sport=80 flags=SA seq=0 win=8192 rtt=20.9 ms
len=46 ip=123.125.115.110 ttl=51 id=6788  sport=80 flags=SA seq=1 win=8192 rtt=20.9 ms
len=46 ip=123.125.115.110 ttl=51 id=37699 sport=80 flags=SA seq=2 win=8192 rtt=20.9 ms

--- baidu.com hping statistic ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 20.9/20.9/20.9 ms

1. TCP/UDP 性能:iperf 或者 netperf

iperf 和 netperf 是最常用的网络性能测试工具,测试 TCP 和 UDP 的吞吐量,它们都以客户端和服务器通信的方式,测试一段时间内的平均吞吐量。

代码语言:javascript
复制
# iperf 安装方式
# Ubuntu
apt-get install iperf3
# CentOS
yum install iperf3

iperf测试方式:

代码语言:javascript
复制
# 被测试机器上启动服务端进行
# -s表示启动服务端,-i表示汇报间隔,-p表示监听端口
$ iperf3 -s -i 1 -p 10000

测试的客户端

代码语言:javascript
复制
# -c表示启动客户端,192.168.0.30为目标服务器的IP
# -b表示目标带宽(单位是bits/s)
# -t表示测试时间,15 表示15秒
# -P表示并发数,-p表示目标服务器监听端口
$ iperf3 -c 192.168.0.30 -b 1G -t 15 -P 2 -p 10000

测试结果报告分析:

代码语言:javascript
复制
[ ID] Interval           Transfer     Bandwidth
...
[SUM]   0.00-15.04  sec  0.00 Bytes  0.00 bits/sec                  sender
[SUM]   0.00-15.04  sec  1.51 GBytes   860 Mbits/sec                  receiver
# 吞吐量是:860 Mb/s,传递的消息量是:1.51 GBytes

2.HTTP 的性能: ab、webbench

ab 是 Apache 自带的 HTTP 压测工具,主要测试 HTTP 服务的每秒请求数、请求延迟、吞吐量以及请求延迟的分布情况等。

代码语言:javascript
复制
# ab的安装
# Ubuntu
$ apt-get install -y apache2-utils
# CentOS
$ yum install -y httpd-tools

目标机器上面运行被测试的服务。 客户端运行ab进行测试:

代码语言:javascript
复制
# -c表示并发请求数为1000,-n表示总的请求数为10000,http://192.168.0.30/ 测试的测试服务的接口
$ab -c 1000 -n 10000 http://192.168.0.30/
...
Server Software:        nginx/1.15.8
Server Hostname:        192.168.0.30
Server Port:            80

...
# 请求汇总、
Requests per second:    1078.54 [#/sec] (mean)
Time per request:       927.183 [ms] (mean)
Time per request:       0.927 [ms] (mean, across all concurrent requests)
Transfer rate:          890.00 [Kbytes/sec] received
# 连接时间汇总
Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   27 152.1      1    1038
Processing:     9  207 843.0     22    9242
Waiting:        8  207 843.0     22    9242
Total:         15  233 857.7     23    9268
# 还有请求延迟汇总
Percentage of the requests served within a certain time (ms)
  50%     23
  66%     24
  75%     24
  80%     26
  90%    274
  95%   1195
  98%   2335
  99%   4663
 100%   9268 (longest request)

3.应用负载性能:wrk

wrk是一个 HTTP 性能测试工具,内置了 LuaJIT,方便你根据实际需求,生成所需的请求负载payload,或者自定义响应的处理方法。

安装:

代码语言:javascript
复制
$ https://github.com/wg/wrk
$ cd wrk
$ apt-get install build-essential -y
$ make
$ sudo cp wrk /usr/local/bin/

启动被测试服务之后,客户端运行下面的命令进行测试:

代码语言:javascript
复制
# -c表示并发连接数1000,-t表示线程数为2,被测试服务的接口路径:http://192.168.0.30/
$wrk -c 1000 -t 2 http://192.168.0.30/
Running 10s test @ http://192.168.0.30/
  2 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    65.83ms  174.06ms   1.99s    95.85%
    Req/Sec     4.87k   628.73     6.78k    69.00%
  96954 requests in 10.06s, 78.59MB read
  Socket errors: connect 0, read 0, write 0, timeout 179
Requests/sec:   9641.31
Transfer/sec:      7.82MB

tcpdump 和 Wireshark 就是最常用的网络抓包和分析工具,更是分析网络性能必不可少的利器。tcpdump 仅支持命令行格式使用,常用在服务器中抓取和分析网络包。Wireshark 除了可以抓包外,还提供了强大的图形界面和汇总分析工具,在分析复杂的网络情景时,尤为简单和实用。因而,在实际分析网络性能时,先用 tcpdump 抓包,后用 Wireshark 分析,也是一种常用的方法。

参考资料:

https://blog.selectel.com/introduction-dpdk-architecture-principles/ https://www.iovisor.org/technology/xdp https://sq.sf.163.com/blog/article/200008406328934400 Linux 性能优化实战

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 灰子学技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
NAT 网关
NAT 网关(NAT Gateway)提供 IP 地址转换服务,为腾讯云内资源提供高性能的 Internet 访问服务。通过 NAT 网关,在腾讯云上的资源可以更安全的访问 Internet,保护私有网络信息不直接暴露公网;您也可以通过 NAT 网关实现海量的公网访问,最大支持1000万以上的并发连接数;NAT 网关还支持 IP 级流量管控,可实时查看流量数据,帮助您快速定位异常流量,排查网络故障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档