怎么评估系统的网络性能?

本文是通过学习倪朋飞老师的《Linux性能优化实战》 :怎么评估系统的网络性能?

性能指标

在评估网络性能前,我们先要,衡量网络性能的指标。在 Linux 网络基础篇, 我们曾经学习过,带宽、吞吐量、延时、PPS 等,都是最常用的网络性能指标。我们来复习一下它们的具体的含义。

  • 首先,带宽,表示链路的最大传输速率,单位是 b/s(比特 / 秒)。在你为服务器选购网卡时,带宽就是最核心的参考指标。常用的带宽有 1000M、10G、40G、100G 等。
  • 第二,吞吐量,表示没有丢包时的最大数据传输速率,单位通常为 b/s (比特 / 秒)或者 B/s(字节 / 秒)。吞吐量受带宽的限制,吞吐量 / 带宽也就是该网络链路的使用率。
  • 第三,延时,表示从网络请求发出后,一直到收到远端响应,所需要的时间延迟。这个指 标在不同场景中可能会有不同的含义。它可以表示建立连接需要的时间(比如 TCP 握手延时),或者一个数据包往返所需时间(比如 RTT)。
  • 最后,PPS,是 Packet Per Second(包 / 秒)的缩写,表示以网络包为单位的传输速 率。PPS 通常用来评估网络的转发能力,而基于 Linux 服务器的转发,很容易受到网络包 大小的影响(交换机通常不会受到太大影响,即交换机可以线性转发)。

这四个指标中,带宽跟物理网卡配置是直接关联的。一般来说,网卡确定后,带宽也就确定了(当然,实际带宽会受限于整个网络链路中最小的那个模块)。

另外,我们在很多地方听说过“网络带宽测试”,这里测试的实际上不是带宽,而是网络吞吐量。Linux 服务器的网络吞吐量一般会比带宽小,而对交换机等专门的网络设备来 说,吞吐量一般会接近带宽。

最后的 PPS,则是以网络包为单位的网络传输速率,通常用在需要大量转发的场景中。而 对 TCP 或者 Web 服务来说,更多会用并发连接数和每秒请求数(QPS,Query per Second)等指标,它们更能反应实际应用程序的性能。

网络基准测试

熟悉了网络的性能指标后,接下来,我们再来看看,如何通过性能测试来确定这些指标的基准值。

我们可以先思考一个问题。我们已经知道,Linux 网络基于 TCP/IP 协议栈,而不同协议层的行为显然不同。那么,测试之前,我们应该弄清楚,要评估的网络性能,究竟属于协议栈的哪一层?换句话说,我们的应用程序基于协议栈的哪一层呢?

根据我们学过的 TCP/IP 协议栈的原理,这个问题应该不难回答。比如:

  • 基于 HTTP 或者 HTTPS 的 Web 应用程序,显然属于应用层,需要我们测试 HTTP/HTTPS 的性能;
  • 而对大多数游戏服务器和即时通讯服务器来说,为了支持更大的同时在线人数,通常会基于 TCP 或 UDP ,与客户端进行交互,这时就需要我们测试 TCP/UDP 的性能;
  • 还有一些场景,是把 Linux 作为一个软交换机或者路由器来用的。这种情况下, 你更关注网络包的处理能力(即 PPS),重点关注网络层的转发性能。

接下来,我们就从下往上,了解不同协议层的网络性能测试方法。不过要注意,低层协议是其上的各层网络协议的基础。自然,低层协议的性能,也就决定了高层的网络性能。

各协议层的性能测试

转发性能

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

我们使用,Linux 内核自带的高性能网络测试工具 pktgen。 pktgen 支持丰富的自定义选项,方便你根据实际需要构造所需网络包,从而更准确地测 试出目标服务器的性能。

不过,在 Linux 系统中,并不能直接找到 pktgen 命令。因为 pktgen 作为一个内核线程来运行,需要加载 pktgen 内核模块后,再通过 /proc 文件系统来交互。下面就是 pktgen 启动的两个内核线程和 /proc 文件系统的交互文件:

modprobe pktgen
ps -ef | grep pktgen| g rep-v grep 3 
root 26384 2 0 06:17 ?    00:00:00 [kpktgend_0]
root 26385 2 0 06:17 ?    00:00:00 [kpktgend_1]
ls /proc/net/pktgen/
kpktgend_0 kpktgend_1 pgctrl

pktgen 在每个 CPU 上启动一个内核线程,并可以通过 /proc/net/pktgen 下面的同名文件,跟这些线程交互;而 pgctrl 则主要用来控制这次测试的开启和停止。

如果 modprobe 命令执行失败,说明你的内核没有配置
CONFIG_NET_PKTGEN 选项。这就需要你配置 pktgen 内核模块(即
CONFIG_NET_PKTGEN=m)后,重新编译内核,才可以使用。

在使用 pktgen 测试网络性能时,需要先给每个内核线程 kpktgend_X 以及测试网卡,配 置 pktgen 选项,然后再通过 pgctrl 启动测试。

TCP/UDP 性能

说到 TCP 和 UDP 的测试,已经很熟悉了,甚至可能一下子就能想到相应的测试工具,比如 iperf 或者 netperf。

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

接下来,我们就以 iperf 为例,看一下 TCP 性能的测试方法。目前,iperf 的最新版本为 iperf3,你可以运行下面的命令来安装:

yum install iperf3

然后,在目标机器上启动 iperf 服务端:

# -s 表示启动服务端,-i 表示汇报间隔,-p 表示监听端口
iperf3 -s -i 1 -p 10000

接着,在另一台机器上运行 iperf 客户端,运行测试:

# -c 表示启动客户端,192.168.0.30 为目标服务器的 IP 2 # -b 表示目标带宽 (单位是 bits/s)
# -t 表示测试时间
# -P 表示并发数,-p 表示目标服务器监听端口
iperf3 -c 172.31.36.80 -b 10G -t 15 -P 2 -p 10000

稍等一会儿(15 秒)测试结束后,回到目标服务器,查看 iperf 的报告:

[ ID] Interval           Transfer     Bitrate
[  5]   0.00-15.04  sec  1.51 GBytes   860 Mbits/sec                  receiver
[  8]   0.00-15.04  sec  1.24 GBytes   709 Mbits/sec                  receiver
[SUM]   0.00-15.04  sec  2.75 GBytes  1.57 Gbits/sec                  receiver

最后的 SUM 行就是测试的汇总结果,包括测试时间、数据传输量以及带宽等。按照发送和接收,这一部分又分为了 sender 和 receiver 两行。

从测试结果你可以看到,这台机器 TCP 接收的带宽(吞吐量)为 1.57 Gb/s, 跟目标的 10Gb/s 相比,还是有些差距的。

HTTP 性能

从传输层再往上,到了应用层。有的应用程序,会直接基于 TCP 或 UDP 构建服务。当 然,也有大量的应用,基于应用层的协议来构建服务,HTTP 就是最常用的一个应用层协 议。比如,常用的 Apache、Nginx 等各种 Web 服务,都是基于 HTTP。

要测试 HTTP 的性能,也有大量的工具可以使用,比如 ab、webbench 等,都是常用的 HTTP 压力测试工具。其中,ab 是 Apache 自带的 HTTP 压测工具,主要测试 HTTP 服 务的每秒请求数、请求延迟、吞吐量以及请求延迟的分布情况等。

运行下面的命令,你就可以安装 ab 工具:

yum install -y httpd-tools

运行 ab 命令,测试 Nginx 的性能:

# -c 表示并发请求数为 1000,-n 表示总的请求数为 10000
ab -c 1000 -n 10000 http://172.31.36.80/
....
Server Software:        nginx
Server Hostname:        172.31.36.80
Server Port:            80

Document Path:          /
Document Length:        3196 bytes

Concurrency Level:      1000
Time taken for tests:   0.462 seconds
Complete requests:      10000
Failed requests:        4
   (Connect: 0, Receive: 0, Length: 0, Exceptions: 4)
Total transferred:      34460000 bytes
HTML transferred:       31960000 bytes
Requests per second:    21634.86 [#/sec] (mean)
Time per request:       46.222 [ms] (mean)
Time per request:       0.046 [ms] (mean, across all concurrent requests)
Transfer rate:          72806.37 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   12   1.7     12      18
Processing:     5   16   8.5     15     233
Waiting:        0   13   8.4     11     230
Total:         14   28   8.6     27     247

Percentage of the requests served within a certain time (ms)
  50%     27
  66%     29
  75%     31
  80%     31
  90%     34
  95%     36
  98%     40
  99%     41
 100%    247 (longest request)
 

可以看到,ab 的测试结果分为三个部分,分别是请求汇总、连接时间汇总还有请求延迟汇总。以上面的结果为例,我们具体来看。

在请求汇总部分,可以看到:

  • Requests per second: 21634.86
  • 每个请求的延迟(Time per request)分为两行,第一行的 46.222 ms 表示平均延迟,包括了线程运行的调度时间和网络请求响应时间,而下一行的 0.046 ms ,则表示实际请求 的响应时间;
  • Transfer rate 表示吞吐量(BPS)为 72806.37 KB/s。

连接时间汇总部分,则是分别展示了建立连接、请求、等待以及汇总等的各类时间,包括最小、最大、平均以及中值处理时间。

最后的请求延迟汇总部分,则给出了不同时间段内处理请求的百分比,比如, 90% 的请 求,都可以在 34ms 内完成。

应用负载性能

当使用 iperf 或者 ab 等测试工具,得到 TCP、HTTP 等的性能数据后,这些数据是否就能表示应用程序的实际性能呢?我想,那肯定不是的。

比如,应用程序基于 HTTP 协议,为最终用户提供一个 Web 服务。这时,使用 ab 工具,可以得到某个页面的访问性能,但这个结果跟用户的实际请求,很可能不一致。因 为用户请求往往会附带着各种各种的负载(payload),而这些负载会影响 Web 应用程序内部的处理逻辑,从而影响最终性能。

那么,为了得到应用程序的实际性能,就要求性能工具本身可以模拟用户的请求负载,而 iperf、ab 这类工具就无能为力了。但是,我们还可以用 wrk、TCPCopy、Jmeter 或者 LoadRunner 等实现这个目标。

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

wrk 工具本身不提供 yum 或 apt 的安装方法,需要通过源码编译来安装。

git clone https://github.com/wg/wrk.git
cd wrk
make
cp wrk /usr/local/bin/

wrk 的命令行参数比较简单。比如,我们可以用 wrk ,来重新测一下前面已经启动的 Nginx 的性能。

# -c 表示并发连接数 1000,-t 表示线程数为 2
wrk -c 1000 -t 2 http://api.tickeup.com/oss/getstsinfo/
Running 10s test @ http://api.tickeup.com/oss/getstsinfo/
  2 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   286.14ms  207.38ms   1.81s    65.46%
    Req/Sec     1.49k     1.16k    6.24k    77.60%
  25253 requests in 10.03s, 7.60MB read
  Socket errors: connect 0, read 0, write 0, timeout 315
  Non-2xx or 3xx responses: 24950
Requests/sec:   2517.19
Transfer/sec:    775.54KB

这里使用 2 个线程、并发 1000 连接,测试了应用程序的性能。你可以看到,每秒请求数为 2517.19,吞吐量为 775.54KB,平均延迟为 286.14ms。

总结

性能评估是优化网络性能的前提,只有在你发现网络性能瓶颈时,才需要进行网络性能优化。根据TCP/IP 协议栈的原理,不同协议层关注的性能重点不完全一样,也就对应不同的性能测试方法。例如,

  • 在应用层,你可以使用 wrk、Jmeter 等模拟用户的负载,测试应用程序的每秒请求数、 处理延迟、错误数等;
  • 而在传输层,则可以使用 iperf 等工具,测试 TCP 的吞吐情况;
  • 再向下,你还可以用 Linux 内核自带的 pktgen ,测试服务器的 PPS。

由于低层协议是高层协议的基础。所以,一般情况下,我们需要从上到下,对每个协议层进行性能测试,然后根据性能测试的结果,结合 Linux 网络协议栈的原理,找出导致性能瓶颈的根源,进而优化网络性能。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值