干翻 nio ,王炸 io_uring 来了 ,史上最详细说明及最全图解!!

Image
大趋势:全链路异步化,性能提升10倍+ 随着业务的发展,微服务应用的流量越来越大,使用到的资源也越来越多。 在微服务架构下,大量的应用都是 SpringCloud 分布式架构,这种架构总体上是 全链路同步模式 。 全链路同步模式 不仅造成了资源的极大浪费,并且在流量发生激增波动的时候,受制于系统资源而无法快速的扩容。 全球后疫情时代,降本增效是大背景。如何降本增效?一条好的路径: 全链路同步模式  ,升级为  全链路异步模式 。 全链路异步模式 改造 具体的内容,请参考尼恩的深度文章: 全链路异步,让你的 SpringCloud 性能优化10倍+ 先回顾一下全链路同步模式架构图 全链路同步模式  ,如何升级为  全链路异步模式 , 就是一个一个 环节的异步化。 40岁老架构师尼恩,持续深化自己的3高架构知识宇宙,当然首先要去完成一次牛逼的 全链路异步模式 微服务实操,下面是尼恩的实操过程、效果、压测数据(性能足足提升10倍多)。 全链路异步模式 改造 具体的内容,请参考尼恩的深度文章: 全链路异步,让你的 SpringCloud 性能优化10倍+ 并且,上面的文章,作为尼恩 全链路异步的架构知识,收录在《 尼恩Java面试宝典 》V52版的架构专题中 注:本文以 PDF 持续更新,最新尼恩 架构笔记、面试题 的PDF文件,请从这里获取: 语雀 或者 码云 全链路异步化的最终目标 全链路异步化的最终目标,如下图所示: 应用层:编程模型的异步化 框架层:IO线程的异步化 OS层:IO模型的异步化 一:应用层:编程模型的异步化 这个请大家去看 尼恩的 《 响应式 圣经 PDF 》电子书 随着 云原生时代的到来, 底层的 组件编程 越来越 响应式、流化, 从命令式 编程转换到 响应式 编程,在非常多的场景 ,是大势所趋。 而响应式编程, 学习曲线很大, 大家需要多看,多实操。 二:框架层:IO线程的异步化 这个大家 都选择 具有异步 回调功能的 异步线程模型,如 Reactor 线程模型 这个是面试的绝对重点 IO的王者组件,Netty框架,整体就是一个 Reactor 线程模型 实现 也是非常核心的知识,这里不做展开,请大家去看尼恩的畅销书《Java 高并发核心编程卷 1 加强版》。 三:OS层:IO模型的异步化 目前的一个最大难题,是IO模型的异步化。 注意,Netty

网络测试工具详细介绍 -- Iperf、Netperf 、MZ

网络性能测量的五项指标

可用性(availability)
响应时间(response time)
网络利用率(network utilization)
网络吞吐量(network throughput)
网络带宽容量(network bandwidth capacity)

1. 可用性

测试网络性能的第一步是确定网络是否正常工作,最简单的方法是使用 ping 命令。通过向远端的机器发送 icmp echo request,并等待接收 icmp echo reply 来判断远端的机器是否连通,网络是否正常工作。

Ping 命令有非常丰富的命令选项,比如 -c 可以指定发送 echo request 的个数,-s 可以指定每次发送的 ping 包大小。

网络设备内部一般有多个缓冲池,不同的缓冲池使用不同的缓冲区大小,分别用来处理不同大小的分组(packet)。例如交换机中通常具有三种类型的包缓冲:一类针对小的分组,一类针对中等大小的分组,还有一类针对大的分组。为了测试这样的网络设备,测试工具必须要具有发送不同大小分组的能力。Ping 命令的 -s 就可以使用在这种场合。

2. 响应时间

Ping 命令的 echo request/reply 一次往返所花费时间就是响应时间。有很多因素会影响到响应时间,如网段的负荷,网络主机的负荷,广播风暴,工作不正常的网络设备等等。

在网络工作正常时,记录下正常的响应时间。当用户抱怨网络的反应时间慢时,就可以将现在的响应时间与正常的响应时间对比,如果两者差值的波动很大,就能说明网络设备存在故障。

3. 网络利用率

网络利用率是指网络被使用的时间占总时间(即被使用的时间 + 空闲的时间)的比例。比如,Ethernet 虽然是共享的,但同时却只能有一个报文在传输。因此在任一时刻,Ethernet 或者是 100% 的利用率,或者是 0% 的利用率。

计算一个网段的网络利用率相对比较容易,但是确定一个网络的利用率就比较复杂。因此,网络测试工具一般使用网络吞吐量和网络带宽容量来确定网络中两个节点之间的性能。

4. 网络吞吐量

网络吞吐量是指在某个时刻,在网络中的两个节点之间,提供给网络应用的剩余带宽。

网络吞吐量可以帮助寻找网络路径中的瓶颈。比如,即使 client 和 server 都被分别连接到各自的 100M Ethernet 上,但是如果这两个 100M 的 Ethernet 被 10M 的 Ethernet 连接起来,那么 10M 的 Ethernet 就是网络的瓶颈。

网络吞吐量非常依赖于当前的网络负载情况。因此,为了得到正确的网络吞吐量,最好在不同时间(一天中的不同时刻,或者一周中不同的天)分别进行测试,只有这样才能得到对网络吞吐量的全面认识。

有些网络应用程序在开发过程的测试中能够正常运行,但是到实际的网络环境中却无法正常工作(由于没有足够的网络吞吐量)。这是因为测试只是在空闲的网络环境中,没有考虑到实际的网络环境中还存在着其它的各种网络流量。所以,网络吞吐量定义为剩余带宽是有实际意义的。

5. 网络带宽容量

与网络吞吐量不同,网络带宽容量指的是在网络的两个节点之间的最大可用带宽。这是由组成网络的设备的能力所决定的。

测试网络带宽容量有两个困难之处:在网络存在其它网络流量的时候,如何得知网络的最大可用带宽;在测试过程中,如何对现有的网络流量不造成影响。网络测试工具一般采用 packet pairs 和 packet trains 技术来克服这样的困难。

收集网络性能数据的方式

当确定了网络性能的测试指标以后,就需要使用网络测试工具收集相应的性能数据,分别有三种从网络获取数据的方式:

  1. 通过 snmp 协议直接到网络设备中获取,如 net-snmp 工具
  2. 侦听相关的网络性能数据,典型的工具是 tcpdump
  3. 自行产生相应的测试数据,即本文中介绍的 iperf、netperf、mz 工具

Iperf

Iperf 是一个网络性能测试工具。Iperf 可以测试最大 TCP 和 UDP 带宽性能,具有多种参数和 UDP 特性,可以根据需要调整,可以报告带宽、延迟抖动和数据包丢失。
0
客户端与服务器共用选项

命令行选项描述
-u–udp:使用 UDP 方式而不是 TCP 方式。需要客户端与服务器端同时使用此参数。
-p–port : 设置端口,与服务器端的监听端口一致。默认是 5001 端口。
-l–len : 设置读写缓冲区的长度。TCP 方式默认为 8KB,UDP 方式默认为 1470 字节。
-w–window : 设置套接字缓冲区为指定大小。对于 TCP 方式,此设置为 TCP 窗口大小。对于 UDP 方式,此设置为接受 UDP 数据包的缓冲区大小,限制可以接受数据包的最大值。
-m–print_mss : 输出 TCP MSS 值(通过 TCP_MAXSEG 支持)。MSS 值一般比 MTU 值小 40 字节。通常情况


服务器端专用选项

命令行选项描述
-s–server : Iperf 服务器模式
-c–client host : 如果 Iperf 运行在服务器模式,并且用 - c 参数指定一个主机,那么 Iperf 将只接受指定主机的连接。此参数不能工作于 UDP 模式。
-P–parallel: 服务器关闭之前保持的连接数。默认是 0,这意味着永远接受连接。


客户端端专用选项

命令行选项描述
-c–client host : 运行 Iperf 的客户端模式,连接到指定的 Iperf 服务器端。
-b–bandwidth :UDP 模式使用的带宽,必须配合 - u 参数,默认值是 1 Mbit/sec。
-d–dualtest : 运行双测试模式。这将使服务器端反向连接到客户端,使用 - L 参数中指定的端口(或默认使用客户端连接到服务器端的端口)。这些在操作的同时就立即完成了。如果你想要一个交互的测试,请尝试 - r 参数。
-r–tradeoff : 往复测试模式。当客户端到服务器端的测试结束时,服务器端通过 - l 选项指定的端口(或默认为客户端连接到服务器端的端口),反向连接至客户端。当客户端连接终止时,反向连接随即开始。如果需要同时进行双向测试,请尝试 - d 参数。
-L–listenport : 指指定服务端反向连接到客户端时使用的端口。默认使用客户端连接至服务端的端口。
-t–time : 设置传输的总时间。Iperf 在指定的时间内,重复的发送指定长度的数据包。默认是 10 秒钟。
-P–parallel: 线程数。指定客户端与服务端之间使用的线程数。默认是 1 线程。需要客户端与服务器端同时使用此参数。

实例

带宽测试通常采用 UDP 模式,因为能测出极限带宽、时延抖动、丢包率。在进行测试时,首先以链路理论带宽作为数据发送速率进行测试,例如,从客户端到服务器之间的链路的理论带宽为 100Mbps,先用 - b 100M 进行测试,然后根据测试结果(包括实际带宽,时延抖动和丢包率),再以实际带宽作为数据发送速率进行测试,会发现时延抖动和丢包率比第一次好很多,重复测试几次,就能得出稳定的实际带宽。

UDP 模式

服务器端:

iperf -u -s

客户端:

/*在udp模式下,以100Mbps为数据发送速率,客户端到服务器192.168.1.1上传带宽测试,测试时间为60秒*/
iperf -u -c 192.168.1.1 -b 100M -t 60 

/*客户端以5Mbps为数据发送速率,同时向服务器端发起30个连接线程*/
iperf -u -c 192.168.1.1 -b 5M -P 30 -t 60 

/*以100M为数据发送速率,进行上下行带宽测试,-L参数指定本端双测试监听的端口*/
iperf -u -c 192.168.1.1 -b 100M -d -t 60 -L 30000

TCP 模式

服务器端:

iperf -s

客户端:

/*在tcp模式下,客户端到服务器192.168.1.1上传带宽测试,测试时间为60秒*/
iperf -c 192.168.1.1 -t 60 

/*进行上下行带宽测试*/
iperf -c 192.168.1.1 -d -t 60 

/*测试单线程TCP*/
iperfc 192.168.1.1p 12345 –i 1 –t 10 –w 20K

-c:客户端模式,后接服务器ip
-p:后接服务端监听的端口
-i:设置带宽报告的时间间隔,单位为秒
-t:设置测试的时长,单位为秒
-w:设置tcp窗口大小,一般可以不用设置,默认即可

对应服务器端:
iperfsp 12345 –i 1 –t 10 –m -y

/*测试多线程TCP: 客户端同时向服务器端发起30个连接线程*/
iperf -c 192.168.1.1 -P 30 -t 60

发包完成后,可以通过 ifconfig ethx 和 ethtool -S ethx 查看对应收发包情况,确定发包数、包长、是否丢包等。

Netperf

Netperf 是一种网络性能的测量工具,主要针对基于 TCP 或 UDP 的传输。Netperf 根据应用的不同,可以进行不同模式的网络性能测试,即批量数据传输(bulk data transfer)模式和请求 / 应答(request/reponse)模式。

参数说明
-H host指定远端运行 netserver 的 server IP 地址
-l testlen指定测试的时间长度 (秒)
-t testname指定进行的测试类型 (TCP_STREAM,UDP_STREAM,TCP_RR,TCP_CRR,UDP_RR)

可选参数有如下几个:

参数说明
-s size设置本地系统的 socket 发送与接收缓冲大小
-S size设置远端系统的 socket 发送与接收缓冲大小
-m size设置本地系统发送测试分组的大小
-M size设置远端系统接收测试分组的大小
-D对本地与远端系统的 socket 设置 TCP_NODELAY 选项
-r req,resp设置 request 和 reponse 分组的大小

实例:

服务器端:

#./netserver

客户端:

1、批量 (bulk) 网络流量的性能

1) TCP_STREAM

Netperf 缺省情况下进行 TCP 批量传输,即 - t TCP_STREAM。测试过程中,netperf 向 netserver 发送批量的 TCP 数据分组,以确定数据传输过程中的吞吐量:

#./netperf -H 192.168.0.28 -l 60 
TCP STREAM TEST to 192.168.0.28 
Recv   Send    Send 
Socket Socket  Message  Elapsed 
Size   Size    Size     Time     Throughput 
bytes  bytes   bytes    secs.    10^6bits/sec 
87380  16384  16384    60.00      88.00

从 netperf 的结果输出中,我们可以知道以下的一些信息:
1)远端系统(即 server)使用大小为 87380 字节的 socket 接收缓冲
2)本地系统(即 client)使用大小为 16384 字节的 socket 发送缓冲
3)向远端系统发送的测试分组大小为 16384 字节
4)测试经历的时间为 60 秒
5)吞吐量的测试结果表明,TCP 带宽为 88Mbits / 秒

通过修改可选参数,并观察结果的变化,我们可以确定是什么因素影响了连接的吞吐量。例如,如果怀疑路由器由于缺乏足够的缓冲区空间,使得转发大的分组时存在问题,就可以增加测试分组(-m)的大小,以观察吞吐量的变化:

#./netperf -H 192.168.0.28 -l 60 -- -m 2048 
TCP STREAM TEST to 192.168.0.28 
Recv   Send    Send 
Socket Socket  Message  Elapsed 
Size   Size    Size     Time     Throughput 
bytes  bytes   bytes    secs.    10^6bits/sec 
87380  16384   2048    60.00      87.62

在这里,测试分组的大小减少到 2048 字节,而吞吐量却没有很大的变化(与前面例子中测试分组大小为 16K 字节相比)。相反,如果吞吐量有了较大的提升,则说明在网络中间的路由器确实存在缓冲区的问题。

2). UDP_STREAM

UDP_STREAM 用来测试进行 UDP 批量传输时的网络性能。需要特别注意的是,此时测试分组的大小不得大于 socket 的发送与接收缓冲大小,否则 netperf 会报出错提示:

#./netperf -t UDP_STREAM -H 192.168.0.28 -l 60 
UDP UNIDIRECTIONAL SEND TEST to 192.168.0.28 
udp_send: data send error: Message too long

为了避免这样的情况,可以通过命令行参数限定测试分组的大小,或者增加 socket 的发送 / 接收缓冲大小。UDP_STREAM 方式使用与 TCP_STREAM 方式相同的局部命令行参数,因此,这里可以使用 - m 来修改测试中使用分组的大小:

#./netperf -t UDP_STREAM -H 192.168.0.28 -- -m 1024 
UDP UNIDIRECTIONAL SEND TEST to 192.168.0.28 
Socket  Message  Elapsed      Messages 
Size    Size     Time         Okay Errors   Throughput 
bytes   bytes    secs            #      #   10^6bits/sec 
65535    1024    9.99        114127     0      93.55 
65535             9.99        114122            93.54

UDP_STREAM 方式的结果中有两行测试数据
第一行显示的是本地系统的发送统计,这里的吞吐量表示 netperf 向本地 socket 发送分组的能力。但是,我们知道,UDP 是不可靠的传输协议,发送出去的分组数量不一定等于接收到的分组数量。

第二行显示的就是远端系统接收的情况,由于 client 与 server 直接连接在一起,而且网络中没有其它的流量,所以本地系统发送过去的分组几乎都被远端系统正确的接收了,远端系统的吞吐量也几乎等于本地系统的发送吞吐量。但是,在实际环境中,一般远端系统的 socket 缓冲大小不同于本地系统的 socket 缓冲区大小,而且由于 UDP 协议的不可靠性,远端系统的接收吞吐量要远远小于发送出去的吞吐量。

2、请求 / 应答 (request/response) 网络流量的性能

另一类常见的网络流量类型是应用在 client/server 结构中的 request/response 模式。在每次交易(transaction)中,client 向 server 发出小的查询分组,server 接收到请求,经处理后返回大的结果数据。

1) TCP_RR

TCP_RR 方式的测试对象是多次 TCP request 和 response 的交易过程,但是它们发生在同一个 TCP 连接中,这种模式常常出现在数据库应用中。数据库的 client 程序与 server 程序建立一个 TCP 连接以后,就在这个连接中传送数据库的多次交易过程。 用户可以通过 - r 参数来改变 request 和 response 分组的大小,进行更有实际意义的测试:

#./netperf -t TCP_RR -H 192.168.0.28 -- -r 32,1024 
TCP REQUEST/RESPONSE TEST to 192.168.0.28 
Local /Remote 
Socket Size   Request  Resp.   Elapsed  Trans. 
Send   Recv   Size     Size    Time     Rate 
bytes  Bytes  bytes    bytes   secs.    per sec 
16384  87380  32       1024    10.00    4945.97 
16384  87380

从结果中可以看出,增加 request/reponse 分组的大小,会导致交易率明显的下降。
注:相对于实际的系统,这里交易率的计算没有充分考虑到交易过程中的应用程序处理时延,因此结果往往会高于实际情况

2) TCP_CRR

与 TCP_RR 不同,TCP_CRR 为每次交易建立一个新的 TCP 连接。最典型的应用就是 HTTP,每次 HTTP 交易是在一条单独的 TCP 连接中进行的。因此,由于需要不停地建立新的 TCP 连接,并且在交易结束后拆除 TCP 连接,交易率一定会受到很大的影响。

#./netperf -t TCP_CRR -H 192.168.0.28 
TCP Connect/Request/Response TEST to 192.168.0.28 
Local /Remote 
Socket Size   Request  Resp.   Elapsed  Trans. 
Send   Recv   Size     Size    Time     Rate 
bytes  Bytes  bytes    bytes   secs.    per sec 
131070 131070 1        1       9.99     2662.20 
16384  87380

即使是使用一个字节的 request/response 分组,交易率也明显的降低了,只有 2662.20 次 / 秒。

3) UDP_RR

UDP_RR 方式使用 UDP 分组进行 request/response 的交易过程。由于没有 TCP 连接所带来的负担,所以我们推测交易率一定会有相应的提升。

#./netperf -t UDP_RR -H 192.168.0.28 
UDP REQUEST/RESPONSE TEST to 192.168.0.28 
Local /Remote 
Socket Size   Request  Resp.   Elapsed  Trans. 
Send   Recv   Size     Size    Time     Rate 
bytes  Bytes  bytes    bytes   secs.    per sec 
65535  65535  1        1       9.99     10141.16 
65535  65535

结果证实了我们的推测,交易率为 10141.16 次 / 秒,高过 TCP_RR 的数值。不过,如果出现了相反的结果,即交易率反而降低了,也不需要担心,因为这说明了在网络中,路由器或其它的网络设备对 UDP 采用了与 TCP 不同的缓冲区空间和处理技术。

MZ

Mausezahn 是什么?

它是一个用 C 语言开发的快速产生流量的工具,用户可以用它来发送几乎所有可能和不可能产生的包。它可以用来做如下工作:

  1. 流量产生器(比如高压的多点传送网络)
  2. 防火墙和 IDS 的穿透测试
  3. 网络中的 DoS 攻击
  4. 在网络软件或工具中发现 bug
  5. 用大量的 ping 和端口扫描搜索攻击
  6. 测试网络行为在奇怪的环境下(如压力测试,畸形包)
  7. 实验室里教学工具

MZ 是一个有着简单语法和在线帮助的命令行的万能发包工具,它还能用在脚本里做各种测试。目前 mz 只有 Linux 平台的版本或者类似 Unix 平台的版本,没有 windows 版本的。

参数说明
-t指定包类型(IP,UDP,TCP,ARP,BPDU,CDP,部分的 ICMP,RTP,DNS 和 SYSLOG
-a指定源 mac
-b指定目的 mac
-A指定源 ip
-B指定目的 ip
-p指定未加工的帧指定长度(随机字节数);
-P指定 ASCII 字符有效载荷
-r指定 delay 的时间为随机值
-f从文件中读取 ASCII 的有效载荷
-F从文件中读取 16 进制数字的有效载荷
-S模拟方式:电线里不放任何数据,它通常与详细的模式(-v 或者 V)

自动产生包

当前有如下类型包的产生器(ARP,BPDU,CDP,IP,部分的 ICMP,UDP,TCP,RTP,DNS 和 SYSLOG), 对于每个包你都可以指定可选的有效载荷,这既可以用参数 payload(或小写的 p)来表示十六进制符号或直接用 “-P” 选项来表示 ASCII 文本:

# 字节被定义为2个16进制数。多字节必须用空格,冒号,横线或者任何你喜欢的分隔
mz eth0 -t ip p=68:65:6c:6c:6f:20:77:6f:72:6c:64

# ASCII文本
mz eth0 -t ip -P "Hello World"

二层:

默认情况是每次只有一个包发送,如果你想发送多个包可以用选项 -c ,当 count=0 时 mz 会永远发送。

每间隔50毫秒发送100,000个帧:
# mz -c 100000  -d 50msec "aa bb cc dd ...." 

间隔2秒发送一个无穷大的BPDU帧 
# mz -c 0 -d 2s -t bpdu conf 

用最大速度发送帧,用随机的MAC地址和广播的目的地址,另外把帧设置为1000字节:
# mz eth0 -c 0 -a rand -b bcast -p 1000 "08 00 aa bb cc dd" 

在VLAN500发送一个CoS=7的TCP的包
# mz eth0 -t tcp -Q 7:500 "dp=80, flags=rst, p=aa:aa:aa"

发送一个VLAN标志为100(外部)和651(内部)的UDP包 
# mz eth0 -t udp "dp=8888, sp=13442" -P "Mausezahn is great" -Q 100,651

三-七层:

UDP

Mz 支持 UDP 数据包的产生。简单地指定目的地址(-B 选项)并且可选的选择任意的源地址(-A 选项)作为参数,你还可以通过 dp(目的端口)和 sp(源端口)指定端口号以及有效载荷。甚至你可以指定整个端口范围,如此一来就可以发送多个包。

发送测试包到 RTP 端口的范围:

mz eth0 -B 192.168.1.1 -t udp "dp=16384-32767, p=A1:00:CC:00:00:AB:CD:EE:EE:DD:DD:00"

TCP

Mz 运行你很轻松的建 TCP 包。类似 UDP 你可以用 sp 和 dp 来指定源和目标端口参数。接着你可以通过 “|” 作为分隔符直接指定想要的标志如果你想指定多个标志的话。例如,对于 1.1.1.1 的 SYN-Flood 攻击就使用随机的源地址定时的使用所有的 1023 个端口

Comments

Popular posts from this blog

便宜好用又稳定的VPN-桔子云,性价比极高!

V2rayN 电脑客户端如何在 win7/win10/win11上 实现全局代理

IOS小火箭/Shadowsocks无需AppleID即可在线安装!