我是靠谱客的博主 苹果纸鹤,最近开发中收集的这篇文章主要介绍怎么评估系统的网络性能?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 性能指标
    • 网络基准测试
    • 各协议层的性能测试
        • 转发性能
        • TCP/UDP 性能
        • HTTP性能
    • 应用负载性能
    • 总结

评估系统的网络性能,考察系统的处理能力,为容量规划提供基准数据。

性能指标

  • 带宽 : 表示链路的最大传输速率,单位是 b/s(比特 / 秒)。
    • 选购网卡时,带宽是最核心的参考指标,常用的带宽有 1000M、10G、40G、100G 等。
    • 带宽跟物理网卡配置是直接关联的,网卡确定后,带宽也就确定了(当然,实际带宽会受限于整个网络链路中最小的那个模块)。
  • 吞吐量 : 表示没有丢包时的最大数据传输速率,单位通常为 b/s (比特 / 秒)或者 B/s(字节 / 秒)。
    • 吞吐量受带宽的限制,吞吐量 / 带宽也就是该网络链路的使用率。
    • “网络带宽测试”,这里测试的实际上不是带宽,而是网络吞吐量。
    • Linux 服务器的网络吞吐量一般会比带宽小,而对交换机等专门的网络设备来说,吞吐量一般会接近带宽。
  • 延时 : 表示从网络请求发出后,一直到收到远端响应,所需要的时间延迟。这个指标在不同场景中可能会有不同的含义。它可以表示建立连接需要的时间(比如 TCP 握手延时),或者一个数据包往返所需时间(比如 RTT)。
  • PPS : 是 Packet Per Second(包 / 秒)的缩写,表示以网络包为单位的传输速率。
    • PPS 通常用来评估网络的转发能力,而基于 Linux 服务器的转发,很容易受到网络包大小的影响(交换机通常不会受到太大影响,即交换机可以线性转发)。
    • 以网络包为单位的网络传输速率,通常用在需要大量转发的场景中。
    • 对 TCP 或者 Web 服务来说,更多会用并发连接数和每秒请求数(QPS,Query per Second)等指标,它们更能反应实际应用程序的性能。

网络基准测试

Linux 网络基于 TCP/IP 协议栈,而不同协议层的行为显然不同。

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

各协议层的性能测试

从下往上,了解不同协议层的网络性能测试方法是学习的重点。

低层协议是其上的各层网络协议的基础,低层协议的性能,决定了高层的网络性能。

以下所有的测试方法,都需要两台 Linux 虚拟机。

  • 一台可以当作待测试的目标机器
  • 另一台可以当作正在运行网络服务的客户端,用来运行测试工具

转发性能

我们首先来看,网络接口层和网络层,它们主要负责网络包的封装、寻址、路由以及发送和接收。

在这两个网络协议层中,每秒可处理的网络包数 PPS,就是最重要的性能指标。特别是 64B 小包的处理能力,值得特别关注。

那么,如何来测试网络包的处理能力呢?

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

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

下面就是 pktgen 启动的两个内核线程和 /proc 文件系统的交互文件:

$ modprobe pktgen
$ ps -ef | grep pktgen | grep -v grep
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 启动测试。

以发包测试为例,假设发包机器使用的网卡是 eth0,而目标机器的 IP 地址为 192.168.0.30,MAC 地址为 11:11:11:11:11:11。
在这里插入图片描述
接下来,就是一个发包测试的示例。

	# 定义一个工具函数,方便后面配置各种测试选项
	function pgset() {
	    local result
	    echo $1 > $PGDEV
	 
	    result=`cat $PGDEV | fgrep "Result: OK:"`
	    if [ "$result" = "" ]; then
	         cat $PGDEV | fgrep Result:
	    fi
	}
	 
	# 为 0 号线程绑定 eth0 网卡
	PGDEV=/proc/net/pktgen/kpktgend_0
	pgset "rem_device_all"   # 清空网卡绑定
	pgset "add_device eth0"  # 添加 eth0 网卡
	 
	# 配置 eth0 网卡的测试选项
	PGDEV=/proc/net/pktgen/eth0
	pgset "count 1000000"    # 总发包数量
	pgset "delay 5000"       # 不同包之间的发送延迟 (单位纳秒)
	pgset "clone_skb 0"      # SKB 包复制
	pgset "pkt_size 64"      # 网络包大小
	pgset "dst 192.168.0.30" # 目的 IP
	pgset "dst_mac 11:11:11:11:11:11"  # 目的 MAC
	 
	# 启动测试
	PGDEV=/proc/net/pktgen/pgctrl
	pgset "start"

稍等一会儿,测试完成后,结果可以从 /proc 文件系统中获取。通过下面代码段中的内容,我们可以查看刚才的测试报告:

$ cat /proc/net/pktgen/eth0
Params: count 1000000  min_pkt_size: 64  max_pkt_size: 64
     frags: 0  delay: 0  clone_skb: 0  ifname: eth0
     flows: 0 flowlen: 0
...
Current:
     pkts-sofar: 1000000  errors: 0
     started: 1534853256071us  stopped: 1534861576098us idle: 70673us
...
Result: OK: 8320027(c8249354+d70673) usec, 1000000 (64byte,0frags)
  120191pps 61Mb/sec (61537792bps) errors: 0

测试报告主要分为三个部分:

  • 第一部分的 Params 是测试选项
  • 第二部分的 Current 是测试进度,其中, packts so far(pkts-sofar)表示已经发送了 100 万个包,也就表明测试已完成。
  • 第三部分的 Result 是测试结果,包含测试所用时间、网络包数量和分片、PPS、吞吐量以及错误数。

根据上面的结果,我们发现,PPS 为 12 万,吞吐量为 61 Mb/s,没有发生错误,12 万的 PPS 好不好呢?

  • 千兆交换机的 PPS,交换机可以达到线速(满负载时,无差错转发),它的 PPS 就是 1000Mbit 除以以太网帧的大小,即 1000Mbps/((64+20)*8bit) = 1.5 Mpps(其中,20B 为以太网帧前导和帧间距的大小)。
  • 即使是千兆交换机的 PPS,也可以达到 150 万 PPS,比我们测试得到的 12 万大多了。所以,看到这个数值你并不用担心,现在的多核服务器和万兆网卡已经很普遍了,稍做优化就可以达到数百万的 PPS。而且,如果你用了的 DPDK 或 XDP ,还能达到千万数量级。

TCP/UDP 性能

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

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

# Ubuntu
apt-get install iperf3
# CentOS
yum install iperf3

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

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

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

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

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

[ 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

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

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

HTTP性能

从传输层再往上,到了应用层。

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

要测试 HTTP 的性能,也有大量的工具可以使用,比如 ab、webbench 等,都是常用的 HTTP 压力测试工具。

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

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

# Ubuntu
$ apt-get install -y apache2-utils
# CentOS
$ yum install -y httpd-tools

在目标机器上,使用 Docker 启动一个 Nginx 服务,然后用 ab 来测试它的性能。首先,在目标机器上运行下面的命令:

$ docker run -p 80:80 -itd nginx

在另一台机器上,运行 ab 命令,测试 Nginx 的性能:

# -c 表示并发请求数为 1000,-n 表示总的请求数为 10000
$ 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)

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

  • 请求汇总
    • Requests per second 为 1074;
    • 每个请求的延迟(Time per request)分为两行
      • 第一行的 927 ms 表示平均延迟,包括了线程运行的调度时间和网络请求响应时间
      • 下一行的 0.927ms ,则表示实际请求的响应时间;
    • Transfer rate 表示吞吐量(BPS)为 890 KB/s。
  • 连接时间汇总:是分别展示了建立连接、请求、等待以及汇总等的各类时间,包括最小、最大、平均以及中值处理时间。
  • 请求延迟汇总:给出了不同时间段内处理请求的百分比,比如, 90% 的请求,都可以在 274ms 内完成。

应用负载性能

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

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

wrk 工具本身不提供 yum 或 apt 的安装方法,需要通过源码编译来安装。比如,你可以运行下面的命令,来编译和安装 wrk:

$ https://github.com/wg/wrk
$ cd wrk
$ apt-get install build-essential -y
$ make
$ sudo cp wrk /usr/local/bin/

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

# -c 表示并发连接数 1000,-t 表示线程数为 2
$ 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
  • 这里使用 2 个线程、并发 1000 连接,重新测试了 Nginx 的性能。
  • 每秒请求数为 9641,吞吐量为 7.82MB,平均延迟为 65ms,比前面 ab 的测试结果要好很多。

这也说明,性能工具本身的性能,对性能测试也是至关重要的。不合适的性能工具,并不能准确测出应用程序的最佳性能。

当然,wrk 最大的优势,是其内置的 LuaJIT,可以用来实现复杂场景的性能测试。wrk 在调用 Lua 脚本时,可以将 HTTP 请求分为三个阶段,即 setup、running、done,如下图所示:
在这里插入图片描述
比如,你可以在 setup 阶段,为请求设置认证参数(来自于 wrk 官方示例):

-- example script that demonstrates response handling and
-- retrieving an authentication token to set on all future
-- requests
 
token = nil
path  = "/authenticate"
 
request = function()
   return wrk.format("GET", path)
end
 
response = function(status, headers, body)
   if not token and status == 200 then
      token = headers["X-Token"]
      path  = "/resource"
      wrk.headers["X-Token"] = token
   end
end

而在执行测试时,通过 -s 选项,执行脚本的路径:

$ wrk -c 1000 -t 2 -s auth.lua http://192.168.0.30/

wrk 需要你用 Lua 脚本,来构造请求负载。这对于大部分场景来说,可能已经足够了 。不过,它的缺点也正是,所有东西都需要代码来构造,并且工具本身不提供 GUI 环境。

像 Jmeter 或者 LoadRunner(商业产品),则针对复杂场景提供了脚本录制、回放、GUI 等更丰富的功能,使用起来也更加方便。

总结

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

  • 在应用层,我们关注的是应用程序的并发连接数、每秒请求数、处理延迟、错误数等,可以使用 wrk、JMeter 等工具,模拟用户的负载,得到想要的测试结果。
  • 在传输层,我们关注的是 TCP、UDP 等传输层协议的工作状况,比如 TCP 连接数、 TCP 重传、TCP 错误数等。此时,你可以使用 iperf、netperf 等,来测试 TCP 或 UDP 的性能。
  • 网络层,我们关注的则是网络包的处理能力,即 PPS。Linux 内核自带的 pktgen,就可以帮你测试这个指标。

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

最后

以上就是苹果纸鹤为你收集整理的怎么评估系统的网络性能?的全部内容,希望文章能够帮你解决怎么评估系统的网络性能?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部