四层TCP协议测试利器-Tcpkali

前言

tcpkali在github项目的地址如下:https://github.com/satori-com/tcpkali。

本文详述TCPkali的基本测试用法。TCPkali是一个可以用来测试四层TCP协议,七层HTTP(s)协议和websocket协议的测试工具。当然这个工具最主要的优点用的还是在于能够独立的进行TCP和websocket测试。

安装

tcpkali可以支持在Mac OS,linux和UNIX上安装。博主在实操中所使用linux操作系统,这里主要详述centos7.x版本中的安装。

包安装

在tcpkali的github上推荐使用包安装的方法。但是博主亲自实验之后发现其实在国内包安装没有源码编译安装好用。centos操作系统中要直接安装tcpkali的软件包,需要用到nix工具。而安装nix安装管理工具之后,再去安装tcpkali的包会去nix国外的源去下载,经常访问超时导致安装失败。所以笔者不建议国内的玩家使用这种方式。这里仅给出安装所需的操作步骤

#安装bzip解压工具
yum -y install bzip2*
#访问nix官网下载安装nix安装管理工具,nix是类yum的安装包管理工具,可以通过nix安装可用的包。
curl https://nixos.org/nix/install | sh
#通过nix安装tcpkali的可执行的软件包
nix-env -i tcpkali

源码编译安装

在国内笔者比较推荐使用编译安装的方式在centos的操作系统中安装tcpkali工具。其主要步骤如下

#以最小化安装centos7.5操作系统为例,yum列出了所需要安装的软件包。主要下载所需的编译软件,git安装工具,vim编辑工具。
yum install -y git autoconf automake libtool bison flex gcc-c++ ncurses-devel vim
#在git上拉取所tcpkali的源码
git clone https://github.com/satori-com/tcpkali.git
#切换到tcpkali的下载文件目录
cd tcpkali/
#检测configure文件并更新已经生成的配置文件
test -f configure || autoreconf -i
#编译安装前执行配置文件
./configure
#编译安装,安装完成之后可系统中就可以tab出tcpkali的命令
make && make install

tcpkali命令参数详解

通用配置

-h, --help : 打印出tcpkali的帮助文档并退出。
–version : 打印出tcpkali的版本号并退出
-v, --verbose level :详细打印输出结果,可以增加-v参数的次数来表示详细信息程度。例如想打印更为详细的输出结果可以使用“-vvv”。也可以使用“–verbose 3”来表示打印输出信息的详细程度。默认的详细信息程度从0-3。
-d, --dump-one : 选择在任意的一个链接上打印出该链接输入或者输出的数据。当该链接被关闭时,将会使用其他链接来进行转储信息。主要用来诊断链接中收发信息是否符合预期。
–dump-one-in : 只转储单个连接上的输入数据。
–dump-one-out : 只转储单个连接上的输出数据。
–dump-{all,all-in,all-out} : 转储所有链接上的输入输出数据。
–write-combine=off : 单独发送消息而不是批量的写入消息. 该参数设置为off则暗示着 --nagle=off, 如果没有在命令行显示调用将其关闭,这该参数默认是开启的。
-w, --workers N : 要使用的并行线程数。默认值是根据需要使用尽可能多的内核,最多使用系统中检测到的内核数量。

网络堆栈参数的设置

–nagle=on|off : 通过使用setsockopt()设置TCP_NODELAY套接字选项来控制Nagle算法。默认情况下根本不调用setsockopt(),这使得Nagle在大多数系统上都是启用的。
–rcvbuf SizeBytes : 设置TCP接收缓冲区(使用setsockopt()设置SO_RCVBUF套接字选项)。此选项对具有自动接收缓冲区管理的某些系统无效。如果rcvbuf不起作用,tcpkali将打印一条消息。
–sndbuf SizeBytes : 设置TCP发送缓冲区(使用setsockopt()设置SO_SNDBUF套接字选项)。此选项对具有自动接收缓冲区管理的某些系统无效。如果sndvbuf不起作用,tcpkali将打印一条消息。
–source-ip IP : 默认情况下,tcpkali自动检测当前主机端口并使用所有可用接口连接到目标主机。这个默认行为允许tcpkali打开到目的地的超过64k个连接。使用**–source- IP 通过指定要使用的特定源IP来覆盖此行为。多次指定–source-ip**选项将构建要使用的源ip列表。

运行测试时设置

–ws, --websocket : 使用RFC6455规范进行WebSocket通信传输。
–ssl : 为客户端和服务器端连接启用传输层安全性(TLS,以前称为SSL)。
–ssl-cert filename : 使用X.509证书来进行TLS加密传输。 默认 “cert.pem”。
–ssl-key filename :使用私钥文件来进行TLS加密传输。默认 “key.pem”。
-H, --header : 添加指定HTTP包头到WebSocket握手中。
-c, --connections N : 打开到目标的并发连接数。默认值为1。
–connect-rate Rate : 限制每秒新连接的数量。默认值是每秒100个连接。
–connect-timeout Time : 限制尝试连接中花费的时间。默认值是1秒。
–channel-lifetime Time : 在设置的时间秒数后关闭每个连接。
–channel-bandwidth-upstream Bandwidth : 限制单个连接的上行带宽。
–channel-bandwidth-downstream Bandwidth : 限制单个连接的下行带宽。
-l, --listen-port port : tcpkali作为服务端接收指定端口上的链接。
–listen-mode=silent|active : 在接收到新建连接时执行操作。在静默模式下(silent),tcpkali不发送数据并忽略接收到的数据,这是默认值。在活动模式下(active),tcpkali向连接的客户机发送消息。消息需要由message参数指定。
-T, --duration Time : 退出并在指定的时间之后打印最终统计信息。默认为10秒(-T10s)。
–delay-send Time : 将发送字节延迟到指定的时间量。

网络流量选项

-e, --unescape-message-args : 如在tcpkali命令行上使用了-m、-f或其他发送了流量内容的指定选项,则发送的消息数据不会进行转义。将\xxx序列转换为具有相应八进制值的字节,将\n转换为换行符,等等。
-1, --first-message : 首先发送此消息,在每个新建连接开始时发送一次。可以多次指定此选项,以便在每个连接开始时发送几个初始消息。如果–websocket选项被给出使用,每个消息都被包装到它自己的websocket框架中。
–first-message-file filename : 从文件中读取消息,并在每个连接开始时发送一次。可以多次指定此选项。
-m, --message string : 从文件中读取消息,并在每个连接开始时发送一次。可以多次指定此选项.
–message-stop string : 如果在接收到的字节流中遇到给定字符串,则终止tcpkali。
-f, --message-file filename : 重复地将从文件读取的消息发送到目标地址。可以多次指定此选项。
-r, --message-rate Rate : 在连接中每秒发送的消息数。tcpkali试图保留消息边界。此设置与–channel-bandwidth-upstream选项互不兼容,因为它们都控制消息发送速率。
-r, --message-rate @Latency : 不要指定消息速率,而是尝试计算不会导致超过给定消息延迟的最大消息速率。需要设置“ --latency-marker”延迟标记选项。

示例: tcpkali -m "PING" --latency-marker "PONG" -r @100ms

时延计算选项

tcpkali可以测量TCP连接延迟,tcpkali会标记指定接收特定的字节。当接收到特定标记的第一个字节时计算时间和请求-响应延迟。
–latency-connect : 测量TCP连接延迟。
–latency-first-byte : 测量第一个字节的延迟。只适用于活动套接字。
tcpkali通过重复记录每次发送消息的时间(由-m或-f指定)与在下行流量中观察到延迟标记的时间(由–latency-marker标记设置)之间的时间差来度量请求-响应延迟。
–latency-marker string : 指定要在数据流中查找的每个消息的特定字符序列。
–latency-marker-skip N : 忽略掉前N个特定字符值,该字符由–latency-marker标记。
–latency-percentiles list : 报告指定百分比的延迟。该选项采用逗号分隔的浮点值列表。平均值和最大值可以使用 --latency-percentiles 50,100报告。默认是95、99、99.5。
00
–message-marker : 被动模式下的检查或消息标记。给定此选项,tcpkali将检测{message.marker}字节序列,并将计算消息速率(以每秒消息数为单位)和消息到达延迟。在活动模式下,通过隐式启动{message.marker}}表达式来计算消息速率。

STATSD选项

StatsD 就是一个简单的网络守护进程,基于 Node.js 平台,通过 UDP 或者 TCP 方式侦听各种统计信息,包括计数器和定时器,并发送聚合信息到后端服务

–statsd : 启用StatsD输出。默认情况下禁用StatsD输出。
–statsd-host host : 将数据发送到指定的statsd主机上。默认是本地。
–statsd-port port : 使用StatsD端口。默认是8125。
–statsd-namespace string : 指定命名空间,默认是“tcpkali”。
–statsd-latency-window Time : 默认情况下,测量延时是在tcpkali运行的整个持续时间(由–duration或-T设置)内进行。此选项指示tcpkali每次将延迟数据刷新到StatsD并重新开始测量延迟的时间。在tcpkali整个运行过程中,用户界面中显示的延迟仍然被收集。

操作系统优化

使用tcpkali需要关注的一点是如何打开想要的并发连接数。不难想象如果一个机器有一张网卡,网卡上配置了一个IP。那么这台机器和目标“IP:端口”所能建立的并发链接数就可以达到6.4W。如果有多个网卡的话那么就可以达到十万以上的并发。在执行压测之前需要对系统进行一些优化使其能够打开你需要并发链接。

  1. 放开对用户限制打开的最大文件数

      vim  /etc/security/limit.conf
        * soft core unlimited
        * hard core unlimited
        * soft nofile 1024000
        * hard nofile 1024000
        #添加如下配置项,使root用户的最大文件数可到百万级别
        root soft nofile 1024000
        root hard nofile 1024000
  1. 设置sysctl.conf配置内核参数
vim sysctl.conf
#设置系统可打开的最大文件句柄数,该参数与第一步修改的用户可打开文件数相互作用
fs.file-max=130000 #这里给出的配置公式是:10000+2*N(N为你想打开的最大连接数)
net.ipv4.tcp_max_orphans=60000

#For load-generating clients.
net.ipv4.ip_local_port_range=1024  65535 #放开系统端口限制,可以允许使用1024之后65535之前的任意端口
net.ipv4.tcp_tw_reuse=1 #开启端口复用技术

tcpkali压测示例

就笔者实际使用tcpkali经验,tcpkali可以执行以下三种测试任务:

  1. 对http(s)进行压测,测量固定并发,消息速率下的带宽吞吐和时延。
  2. 对websocket服务进行压测,测量固定并发,消息速率下的带宽吞吐和时延。
  3. 通过搭建tcpkali服务端和客户端,对四层tcp协议的负载均衡器进行固定并发,消息速率下的带宽吞吐和时延性能测试。

压测webserver

首先看一下tcpkali如何压测webserver。这里压测端是一个使用nginx搭建的静态页面webserver。tcpkali作为压力端虚机上有三张网卡,ip分别为10.130.1.71/24,10.130.1.11/24,10.130.1.110/24。nginx服务端只有一张网卡ip为10.130.1.217/24。

客户端使用单网卡压测:

#这里发送的消息转义之后就是一个GET请求
# tcpkali   --connections 6000 --connect-rate 6000  -T 120s -em "GET / HTTP/1.1\r\nHost: 10.130.1.217\r\n\r\n"  10.130.1.217:80
Destination: [10.130.1.217]:80
Interface eth0 address [10.130.1.71]:0
Using interface eth0 to connect to [10.130.1.217]:80
Ramped up to 6000 connections.
?  Traffic 220.537↓, 16363.188↑ Mbps (conns 0↓ 4262↑ 1736⇡; seen 21656)

等待测试执行结束之后打印出结果如下:
# tcpkali   --connections 6000 --connect-rate 6000  -T 120s -em "GET / HTTP/1.1\r\nHost: 10.130.1.217\r\n\r\n"  10.130.1.217:80
Destination: [10.130.1.217]:80
Interface eth0 address [10.130.1.71]:0
Using interface eth0 to connect to [10.130.1.217]:80
Ramped up to 6000 connections.
Total data sent:     34716.8 MiB (36403218124 bytes)
Total data received: 1535.0 MiB (1609569208 bytes)
Bandwidth per channel: 0.479⇅ Mbps (59.9 kBps)
Aggregate bandwidth: 107.304↓, 2426.878↑ Mbps
Packet rate estimate: 15806.7↓, 207872.1↑ (2↓, 42↑ TCP MSS/op)
Test duration: 120 s.

nginx服务端观测到并发连接数如下:
可以看到在压测七层webserver时,压力端指定的并发连接数并不能达到,主要原因是有nginx服务端关闭连接造成。

Total: 8534 (kernel 8552)
TCP:   18313 (estab 816, closed 7288, orphaned 2809, synrecv 0, timewait 7288/0), ports 0

Transport Total     IP        IPv6
*         8552      -         -
RAW	  0         0         0
UDP	  8         5         3
TCP	  11025     11019     6
INET	  11033     11024     9
FRAG	  0         0         0

使用tcpkali服务端压测四层tcp连接

服务器端监听12345端口,接收到的包不做回应并丢弃:

#tcpkali -l 12345 -T 720

Every 1.0s: ss -s                                                                                                                                                                                                   Sun Aug 11 16:11:55 2019
#检测到实际建立链接的并发量也就在6.4W左右
Total: 64178 (kernel 64311)
TCP:   63864 (estab 63839, closed 0, orphaned 2, synrecv 0, timewait 0/0), ports 0

Transport Total     IP        IPv6
*         64311     -         -
RAW	  0         0         0
UDP	  8         5         3
TCP	  63864     63854     10
INET	  63872     63859     13
FRAG	  0         0         0

客户端tcpkali虚机上有三张网卡,ip分别为10.130.1.71/24,10.130.1.11/24,10.130.1.110/24。使用–source-ip参数分别指定三张网卡来发起并发链接,每个连接每秒钟传输一个"PING"消息。发现客户端仍然只能建立6.4W个链接。使用-vvv打印详细的建立链接过程发现仍然是用三个网卡与对端建立链接的。但是链接超时。

# tcpkali --source-ip 10.130.1.71 --source-ip 10.130.1.11 --source-ip 10.130.1.110  --connections 180000 --connect-rate 100000 -m "PING" --message-rate 1 -T 120s   10.130.1.217:12345
WARNING: Will not be able to open 180000 simultaneous connections since "/proc/sys/net/ipv4/ip_local_port_range" specifies too narrow range [1025..65534].
Destination: [10.130.1.217]:12345
Source IP: [10.130.1.71]:0
Source IP: [10.130.1.11]:0
Source IP: [10.130.1.110]:0
|================>--------------------------------| 62437 of 180000 (358005)


Connection [10.130.1.11]:48233 -> [10.130.1.217]:12345 opened as 198
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection [10.130.1.11]:43493 -> [10.130.1.217]:12345 opened as 207
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection [10.130.1.71]:10702 -> [10.130.1.217]:12345 opened as 188
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection [10.130.1.110]:9942 -> [10.130.1.217]:12345 opened as 213
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection to [10.130.1.217]:12345 is being closed: Connection timed out
Connection [10.130.1.71]:53393 -> [10.130.1.217]:12345 opened as 216

使用多网卡压测

这里笔者作死去压测百度的公网,然后居然能压测上…

 tcpkali  --source-ip 10.130.1.71 --source-ip 10.130.1.11 --source-ip 10.130.1.110  --connections 80000 --connect-rate 1000000 -T 120s   www.baidu.com:80
WARNING: Will not be able to open 80000 simultaneous connections since "/proc/sys/net/ipv4/ip_local_port_range" specifies too narrow range [1025..65534].
Destination: [180.97.33.108]:80
Destination: [180.97.33.107]:80
Source IP: [10.130.1.71]:0
Source IP: [10.130.1.11]:0
Source IP: [10.130.1.110]:0
Ramped up to 80000 connections.
?  Traffic 0.000↓, 0.000↑ Mbps (conns 0↓ 4015↑ 75985⇡; seen 2042906)

在本地使用tcpkali监听12345端口,压测127.0.0.1本地环回IP地址。

执行压测命令


# tcpkali  --source-ip 10.130.1.71 --source-ip 10.130.1.11 --source-ip 10.130.1.110  --connections 180000 --connect-rate 1000000 -T 120s   127.0.0.1:12345
WARNING: Will not be able to open 180000 simultaneous connections since "/proc/sys/net/ipv4/ip_local_port_range" specifies too narrow range [1025..65534].
Destination: [127.0.0.1]:12345
Source IP: [10.130.1.71]:0
Source IP: [10.130.1.11]:0
Source IP: [10.130.1.110]:0
Ramped up to 180000 connections.
?  Traffic 0.000↓, 0.000↑ Mbps (conns 0↓ 139753↑ 45446⇡; seen 843272)

执行监听端口命令并观察并发连接数

# tcpkali -l 12345 -T 720
Listen on: [0.0.0.0]:12345
Listen on: [::]:12345
?  Traffic 0.000↓, 0.000↑ Mbps (conns 130903↓ 0↑ 0⇡; seen 112385088)
#watch -n 1 "ss -s"

Every 1.0s: ss -s                                                                              Mon Aug 12 00:23:35 2019

Total: 300915 (kernel 304725)
TCP:   308814 (estab 278546, closed 6, orphaned 126, synrecv 0, timewait 6/0), ports 0

Transport Total     IP        IPv6
*         304725    -         -
RAW	  2         0         2
UDP	  3         3         0
TCP	  308808    308773    35
INET	  308813    308776    37
FRAG	  0         0         0

tcpkali工具优劣分析

优点

  1. 可以当做服务端的测试工具。
    tcpkali主要的优势就在于它是C/S架构的测试工具。它可以在一台服务器上监听固定端口的所收到的流量并可以选择对接收到的信息做回应。作为服务器tcpkali可以按照测试计划接受压力端发来的请求包并按照你输入的参数对包做丢弃或者回应。你可以将TCPkali拿来单独作为测试工具使用对服务器建立连接发起请求。你也可以使用tcpkal作为服务器建监听某个端口,然后使用tcpkali的客户端对该监听端口发起请求。这种模式的主要好处在于你可以针对网络系统中的四层负载均衡器或者代理服务器性能进行测试。
  2. 可以测试使用TCP和websocket协议,固定并发下的带宽和时延。
  3. 对流量和时延的控制,可以说很少有工具可以针对每个链接来控制流量和时延。
  4. tcpkali客户端如有多个IP地址的情况下,可以指定一个或者若干个系统已经配置的IP地址来对服务端发起请求。如果想要测试四层负载均衡器,代理服务器的并发性能。根据四层传输层协议五元组,目的端提供服务的端口与IP不变的情况下,如果你客户端无法启用更多的IP地址和端口,那所能建立起来的并发链接是有限(6.4W个左右就是极限,系统保留0-1024端口号,而端口号可用上限到65535)。但是笔者认为这个功能不是非常好用

缺点

  1. tcpkali作为一个性能测试工具而言是很好,但是作为基准测试工具来说就另当别论了。最主要的一点就是tcpkali客户端和服务端的执行时间是可以单独设定的。所以最后反馈的报告结果上看服务端的吞吐和客户端发送的吞吐存在一定的误差。如果将tcpkali服务器端的测试执行时间大于tcpkali客户端的测试时间。则服务端的每秒处理包速率会相对较低。
  2. tcpkali不具备分布式的能力,虽然它可以在单机上利用多IP来制造高并发,但这非常考验压力机的机器性能。
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值