高性能 HTTP 负载测试工具 Vegeta及并行分布式运维工具pdsh

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高性能 HTTP 负载测试工具 Vegeta及并行分布式运维工具pdsh相关的知识,希望对你有一定的参考价值。

什么是 Vegeta

Vegeta 是一个用 Go 语言编写的多功能的 HTTP 负载测试工具,它提供了命令行工具和一个开发库。 

官方地址:https://github.com/tsenart/vegeta

安装 Vegeta

Vegeta 安装非常简单,由于 Go 语言良好的跨平台性,可以直接下载官方的预编译版本后开箱即用。

  • 预编译版本

这里以 Linux 版本为例:

$ wget https://github.com/tsenart/vegeta/releases/download/v7.0.3/vegeta-7.0.3-linux-amd64.tar.gz
$ tar xzvf vegeta-7.0.3-linux-amd64.tar.gz
$ mv vegeta  /usr/local/bin/

Vegeta 用法

$ vegeta --help
Usage: vegeta [global flags] <command> [command flags]

global flags:
  -cpus int
    使用 CPU 的数量 (默认为 4 个)
  -profile string
    指定在执行期间启用哪个分析器,支持 cpu 和 heap。
  -version
    打印版本并退出。

attack command:
  -body string
    指定请求主体文件里的内容。
  -cert string
    指定用于 HTTPS 请求的 PEM 格式的客户端证书文件。如果 -key 未指定,它会被设置为这个标志的值。
  -connections int
    指定每个目标主机打开的空闲连接的最大数目,默认值为 10000。
  -duration duration
    指定发送请求到目标主机的时长,用 0 表示永久。
  -header value
    指定目标的请求头,可以重复指定多个请求头。
  -http2
    指定是否向支持的服务器发送 HTTP/2 请求,默认为:true。
  -insecure
    指定是否忽略无效的服务器 TLS 证书。
  -keepalive
    指定是否使用持久链接,默认值为:true。
  -key string
    指定 HTTPS 请求中使用的 PEM 编码的 SSL 客户端证书私钥文件。
  -laddr value
    指定要使用的本地 I P地址,默认值为:0.0.0.0。
  -lazy
    指定是否使用延迟模式读取目标。
  -output string
    指定输出文件的位置,默认为标准输出。
  -rate uint
    指定每秒钟对目标发送的请求数,默认值为:50。
  -redirects int
    指定每个请求的重定向的最大次数,默认为 10 次。当值为 -1, 不会遵循重定向但响应标记为成功。
  -root-certs value
    指定可信的 TLS 根证书文件,多个的情况下使用逗号分隔。如果未指定,使用系统默认的 CA 证书。
  -targets string
    指定目标文件,默认为标准输入。
  -timeout duration
    指定每个请求的超时时间,默认值为 30s。
  -workers uint
    指定初始化进程数量,默认值为 10。

report command:
  -inputs string
    指定报告输入文件,默认为标准输入。
  -output string
    指定报告输出文件,默认为标准输出。
  -reporter string
    指定要生成的报告的格式,支持 text,json, plot, hist[buckets]。默认为文本。

dump command:
  -dumper string
    指定转存文件,支持 json, csv 格式。默认为 json 格式。
  -inputs string
    指定要转存的输入文件,默认为标准输入,指定多个用逗号分隔。
  -output string
    指定要转存的输出文件,默认为标准输出。

Vegeta 使用实例

使用标准输入进行压测并生成报告

$ echo "GET http://www.hi-linux.com/img/linux/docker-dry-01.png" | vegeta attack -rate=50 -connections=1 -duration=1s | tee results.bin | vegeta report

Requests      [total, rate]            50, 51.02
Duration      [total, attack, wait]    37.41975091s, 979.999689ms, 36.439751221s
Latencies     [mean, 50, 95, 99, max]  33.816664905s, 35.021110945s, 37.058121168s, 37.204824958s, 37.319751221s
Bytes In      [total, mean]            9505000, 190100.00
Bytes Out     [total, mean]            0, 0.00
Success       [ratio]                  100.00%
Status Codes  [code:count]             200:50
Error Set:

使用目标文件的内容进行压测

  • 创建 target.txt 文件,内容如下:

$ vim target.txt
GET http://www.hi-linux.com/
GET http://www.hi-linux.com/posts/19779.html
GET http://www.hi-linux.com/img/linux/docker-dry-01.png
  • 使用 Vegeta 进行压测

$ vegeta attack -targets="target.txt" -rate=10 -duration=2s  > results.bin
  • 自定义目标文件

除了前面定义的最简单 HTTP GET 请求外,你还可以定义下面这些更灵活更复杂的 HTTP 请求:

1. 自定义请求头

GET http://user:[email protected]:80/path/to
X-Account-ID: 8675309

DELETE http://hi-linux.com:80/path/to/remove
Confirmation-Token: 90215
Authorization: Token DEADBEEF

2. 自定义请求的主体

POST http://hi-linux.com:80/things
@/path/to/newthing.json

PATCH http://hi-linux.com:80/thing/71988591
@/path/to/thing-71988591.json

3. 自定义请求头和请求主体

POST http://hi-linux.com:80/things
X-Account-ID: 99
@/path/to/newthing.json

生成压测报告

  • 生成 JSON 格式的压测报告

$ vegeta report -inputs=results.bin -reporter=json > metrics.json
  • 生成基于 Dygraphs 的 HTML 5 压测报告

$ cat results.bin | vegeta report -reporter=plot > plot.html
  • 计算并输出一个基于文本的直方图

$ cat results.bin | vegeta report -reporter="hist[0,2ms,4ms,6ms]"

Bucket         #     %       Histogram
[0,     2ms]   6007  32.65%  ########################
[2ms,   4ms]   5505  29.92%  ######################
[4ms,   6ms]   2117  11.51%  ########
[6ms,   +Inf]  4771  25.93%  ###################


生成实时图形压测报告

如果您是 iTerm 用户,可以使用 jaggr 将 Vegeta 与 jplot 整合在一起并在终端上实时绘制压测报告。要实现这个功能你首先需要先安装 jaggr 和 jplot:
1. 安装 jaggr(linux上也可以用)
# macOS
$ brew install rs/tap/jaggr

# 源代码安装
$ go get -u github.com/rs/jaggr

2. 安装 jplot(This tool does only work with iTerm2)
# macOS
$ brew install rs/tap/jplot

# 源代码安装
go get -u github.com/rs/jplot
安装完 jaggr 和 jplot 后,其次你需要在 iTerm 中执行以下命令:
$ echo 'GET http://www.hi-linux.com' | vegeta attack -rate 50 -duration 5m | vegeta dump | jaggr @count=rps hist[100,200,300,400,500]:code p25,p50,p95:latency sum:bytes_in sum:bytes_out | jplot rps+code.hist.100+code.hist.200+code.hist.300+code.hist.400+code.hist.500 latency.p95+latency.p50+latency.p25 bytes_in.sum+bytes_out.sum
分布式压力测试
当进行大规模负载测试时,通常由于受限于 Vegeta 自身机器的性能瓶颈(比如:打开的文件数,内存大小,CPU 和 网络带宽)限制而无法达到预期结果。 这时分布式的使用 Vegeta 可以很好的解决这个问题,实现类似功能的工具很多,比如功能强大的 Ansible。这里我们使用 Pdsh 来实现:
$ pdsh -b -w '10.0.1.1,10.0.2.1,10.0.3.1'     'echo "GET http://target/" | vegeta attack -rate=20000 -duration=60s > result.bin'
Pdsh 的全称是 (Parallel Distributed Shell),Pdsh 可并行的执行对目标主机的操作,很方便的批量执行命令和分发任务。Pdsh 还支持交互模式,当要执行的命令不确定时,可直接进入 Pdsh命令行,非常方便。
完成前面的命令后,我们就可以通过 Shell 脚本将结果文件收集到的一起供后面生成报表时使用。
$ for machine in "10.0.1.1 10.0.2.1 10.0.3.1"; do
    scp $machine:~/result.bin $machine.bin &
  done
最后我们可以通过 vegeta report 命令生成此次压测的报表。vegeta report 命令可一次性读取使用逗号分隔的多个结果文件并生成报告,默认通过时间戳进行排序。
$ vegeta report -inputs="10.0.1.1.bin,10.0.2.1.bin,10.0.3.1.bin"

Requests      [total, rate]         3600000, 60000.00
Latencies     [mean, 95, 99, max]   223.340085ms, 326.913687ms, 416.537743ms, 7.788103259s
Bytes In      [total, mean]         3714690, 3095.57
Bytes Out     [total, mean]         0, 0.00
Success       [ratio]               100.0%
Status Codes  [code:count]          200:3600000
Error Set:
其它相关
如果你觉得命令行下使用 Vegeta 比较复杂的话,你还可以使用 Alex 项目。Alex 是一个基于 Vegeta Library 和 Boom 封装的压力测试 Web UI,Vegeta 提供稳定的 QPS 压力源,Boom 提供稳定的并发数压力源。
项目地址:https://github.com/ireaderlab/alex
Alex 架构图

Alex 效果图



参考文档
http://www.google.com
http://t.cn/RBqHjIu
http://t.cn/zQ104Zp
http://t.cn/R5spIPf


并行分布式运维工具pdsh安装与实战


并行分布式运维工具pdsh安装与实战

pdsh全称是parallel distributed shell,可以并行执行对远程目标主机的操作,

利于解决批量执行命令或分发任务的运维需求。适用于大批量服务器的配置,部署,文件复制等运维操作。

此外,pdsh支持交互模式,附带pdcp批量复制命令。

pdsh可以通过多种方式在远程主机上运行命令,默认是rsh方式,另外也支持ssh,mrsh,qsh,mqsh,krb4,xcpu等多种rcmd模块,可以在运行命令是通过参数指定。

前提:使用pssh工具包,必须保证本地主机和管理的远程主机之间的单向信任,

也就是要在本地主机和所有远程服务器上配置密钥认证访问。

下载:https://code.google.com/archive/p/pdsh/downloads


一、建立本地主机和管理的远程主机之间的单向信任

[[email protected]~]$ mkdir ~/.ssh

mkdir:无法创建目录"/home/fieldyang/.ssh":文件已存在

[[email protected]~]$ chmod 700 ~/.ssh

[[email protected]~]$ cd ~/.ssh

1使用ssh-keygen命令生成基于SSH协议的RSA秘钥,提示保存位置及密钥时,选择默认,方便使用

[[email protected]]$ ssh-keygen -t rsa

Generatingpublic/private rsa key pair.

Enterfile in which to save the key (/home/fieldyang/.ssh/id_rsa):<-----可以输入存放密钥的地址

Enterpassphrase (empty for no passphrase):<-----输入密语,可以为空

Entersame passphrase again:<-----确认密语,可以为空

Youridentification has been saved in /home/fieldyang/.ssh/id_rsa.<-----生成的密钥

Yourpublic key has been saved in /home/fieldyang/.ssh/id_rsa.pub.<-----生成的公钥

Thekey fingerprint is:

e2:56:ea:0d:62:df:4a:30:e2:b2:1f:5c:d8:ce:33:[email protected]

Thekey's randomart image is:

+--[RSA 2048]----+

| |

| |

| |

| o |

| o = . S |

|o = + + |

|.+ B * |

|o = O + |

|...E +.o |

+-----------------+

2将本地节点生成的公钥文件整合为一个authorized_keys文件,并进行授权

[[email protected]]$ cd ~/.ssh

[[email protected]]$ cat /home/fieldyang/.ssh/id_rsa.pub > authorized_keys

[[email protected]]$ chmod 600 ~/.ssh/authorized_keys

3authorized_keys文件复制到远程主机上

[[email protected]]$ scp authorized_keys192.168.56.103:/home/fieldyang/.ssh/

Theauthenticity of host '192.168.56.103 (192.168.56.103)' can't beestablished.

RSAkey fingerprint is 8a:75:1f:1b:16:cd:ac:0c:8a:f5:be:ea:11:42:d1:f6.

Areyou sure you want to continue connecting (yes/no)? yes

Warning:Permanently added '192.168.56.103' (RSA) to the list of known hosts.

[email protected]'spassword:

authorized_keys 100% 408 0.4KB/s 00:00

4测试ssh密钥认证是否成功建立

[[email protected]]$ ssh slave.field.com date

20170328日星期二17:20:34CST

5、重复以上1~4在所有的远程主机上执行,即可实现本地主机对所有远程主机的单向通信


二、pdsh的安装与用法

1、源码安装pdsh

[[email protected]~]# tar -jxvf pdsh-2.29.tar.bz2

[[email protected]]# ./configure --with-ssh --with-rsh --with-mrsh--with-mqshell --with-qshell --with-dshgroups--with-machines=/etc/pdsh/machines

configure:Cannot support QsNet without libelan3 or libelanctrl!

configure:Cannot support qshell without libelan3 or libelanctrl!

checkingfor pam_start in -lpam... no

configure:Cannot support qshell without libpam

configure:Consider turning off pam support with --without-pam

configure:error: Error configuring qshell

[[email protected]]# make

make:***没有指明目标并且找不到makefile。停止。

[[email protected]]# make install

make:***没有规则可以创建目标“install”。停止。

此处报错,按提示添加--without-pam参数即可正常编译安装

[[email protected]]# ./configure --help

[[email protected]]# ./configure --with-ssh --with-rsh --with-mrsh--with-mqshell --with-qshell --with-dshgroups--with-machines=/etc/pdsh/machines --without-pam

[[email protected]]# make

[[email protected]]# make install

2用法:

[[email protected]]# pdsh -h

Usage:pdsh [-options] command ...

-S return largest of remote command return values

-h output usage menu and quit

-V output version information and quit

查看软件的版本信息以及可用的模块信息

-q list the option settings and quit

列出pdsh执行时的一些配置信息

-b disable ^C status feature (batch mode)

-d enable extra debug information from ^C status

-luser execute remote commands as user

指定在远程主机上使用的用户名。

eg:pdsh -R ssh -l fieldyang -w slave0[1-10] "date"

-tseconds set connect timeout (default is 10 sec)

指定连接远程主机的超时时间,以s为单位,默认是10s

egpdsh-R ssh -w slave0[1-10] -t 15 "date"

-useconds set command timeout (no default)

指定远程命令的超时时间,以s为单位,以SSH方式连接时,默认时间是无限

-fn use fanout of n nodes

同时连接到远程主机的数量

-whost,host,... set target node list on command line

指定远程主机,可以指定多台,每台主机用逗号隔开,host可以使主机名或者IP地址,常用的形式有:

pdsh-w ssh:slave01,ssh:slave02,ssh:slave03 "date"

此命令用来查看slave01/02/03主机上的时间,其中ssh表示在远程主机上执行命令的方式,默认是rsh

pdsh-w ssh:slave0[1-10] "date"

此命令用于在slave01~10主机上执行date命令;

pdsh-w ssh:slave0[10-31],/-$/ "uptime"

此命令在选择远程主机上使用正则表达式,表示选择slave10-31中一1结尾的主机(即11/21/31)执行update命令;

-xhost,host,... set node exclusion list on command line

排除某些或某台主机

egpdsh -R ssh -lfieldyang -w slave0[1-9] -x slave05,slave07 "date"

-Rname set rcmd module to name

指定rcmd的模块名,默认是rsh。如果要选择ssh,可以通过如下方式指定:

eg:pdsh -R ssh -w slave0[1-10] "date"

-Mname,... select one or more misc modules to initialize first

-N disable hostname: labels on output lines

关闭远程主机所返回结果中的主机名显示

-L list info on all loaded modules and exit

-ggroupname target hosts in dsh group "groupname"

指定一组远程主机,在编译pdsh时可以通过“--with-dshgroups”参数来激活此选项,默认可以将一组主机列表写入一个文件中并放到本地主机的~/.dsh/group/etc/dsh/group目录下,这样就可以通过-g参数调用了.

egpdsh-R ssh -g userhosts "date"

userhosts是一个主机列表文件,可以将其放~/.dsh/group/etc/dsh/group目录下

-Xgroupname exclude hosts in dsh group "groupname"

用来排除指定组内的所有主机,经常和-a一起使用

egpdsh-R ssh -a -X userhosts "date"

-a target all nodes

指定所有的远程主机,设置此参数后,pdsh默认会查看/etc/machines文件中的主机列表,要改变此路径,在编译pdsh时通过“--with-machines”参数指定即可

availablercmd modules: ssh,rsh,exec (default: rsh)


三、pdsh应用实例:此处只用两台机做演示,控制多台远程主机操作相同

1查看pdsh版本号以及可使用的模块信息

[[email protected]]# pdsh -V

pdsh-2.29

rcmdmodules: ssh,rsh,exec (default: rsh)

miscmodules: machines,dshgroup

2查看当前所有加载的模块信息

[[email protected]]# pdsh -L

5modules loaded:

Module:misc/dshgroup

Author:Mark Grondona <[email protected]>

Descr: Read list of targets from dsh-style "group" files

Active:yes

Options:

-ggroupname target hosts in dsh group "groupname"

-Xgroupname exclude hosts in dsh group "groupname"

Module:rcmd/exec

Author:Mark Grondona <[email protected]>

Descr: arbitrary command rcmd connect method

Active:yes

Module:misc/machines

Author:Jim Garlick <[email protected]>

Descr: Read list of all nodes from a machines file

Active:yes

Options:

-a target all nodes

Module:rcmd/rsh

Author:Jim Garlick <[email protected]>

Descr: BSD rcmd connect method

Active:yes

Module:rcmd/ssh

Author:Jim Garlick <[email protected]>

Descr: ssh based rcmd connect method

Active:yes

3、利用pdsh统计主机信息,-w参数后可接多个主机

[[email protected]~]$ pdsh -w ssh:192.168.56.103 "uname -r"

192.168.56.103:2.6.32-642.1.1.el6.x86_64

[[email protected]~]$ pdsh -w ssh:192.168.56.103 "uname -n"

192.168.56.103:slave.field.com

[[email protected]~]$ pdsh -w ssh:192.168.56.103 "uptime"

192.168.56.103: 11:03:17 up 1:33, 2 users, load average: 0.85, 0.89, 0.87

[[email protected]~]$ pdsh -wssh:slave.field.com,ssh:slave.field.com,ssh:slave.field.com "date"

slave:20170330日星期四11:21:02 CST

slave:20170330日星期四11:21:02 CST

slave:20170330日星期四11:21:02 CST

4将主机名写入文件中,利用pdsh批量执行

[[email protected]~]# mkdir /etc/pdsh/

[[email protected]~]# vim /etc/pdsh/machines

[[email protected]~]# chmod 777 /etc/pdsh/machines

[[email protected]~]$ more /etc/pdsh/machines

slave.field.com

slave.field.com

slave.field.com

[[email protected]~]$ pdsh -R ssh -a uptime

slave: 11:09:32 up 1:40, 2 users, load average: 0.62, 0.71, 0.80

slave: 11:09:32 up 1:40, 2 users, load average: 0.62, 0.71, 0.80

slave: 11:09:32 up 1:40, 2 users, load average: 0.62, 0.71, 0.80

#该例中,演示将所有远程主机主机名都写入到本地主机的/etc/pdsh/machines文件中,

这个路径是在编译pdsh时通过“--with-machines”参数指定的。只需利用-a参数即可在所有主机上执行

5利用pdsh实现远程主机分组管理

[[email protected]~]# mkdir /etc/dsh/group

[[email protected]~]# vim /etc/dsh/group/userhosts

[[email protected]~]# chmod 777 /etc/dsh/group/userhosts

[[email protected]~]$ more /etc/dsh/group/userhosts

slave.field.com

slave.field.com

[[email protected]~]$ pdsh -R ssh -g userhosts uptime

slave: 11:13:19 up 1:44, 2 users, load average: 0.55, 0.64, 0.76

#该例中,将某些服务器主机名写入userhosts文件中,利用-g参数调用即可在相关远程主机上执行。

大规模运维环境中,可以分别分为web服务器组,数据库服务器组等。

#要实现远程主机的分组管理,需要激活pdshdshgroup模块,也就是在编译的pdsh的时候指定“--with-dshgroups”参数,

激活这个参数后,就可以将不同用途的服务器进行分组,可以不同组主机列表写入不同文件中,

并放到本地主机的~/.dsh/group/etc/dsh/group目录下。

[[email protected]~]$ pdsh -R ssh -a -X userhosts uptime

slave: 11:13:39 up 1:44, 2 users, load average: 0.81, 0.69, 0.77

slave: 11:13:39 up 1:44, 2 users, load average: 0.81, 0.69, 0.77

#-a参数指定所有主机,-X排除某些主机,-R指定ssh模块

6pdsh在远程主机上执行命令

[[email protected]~]$ pdsh -R ssh -g userhosts "rm -rf /home/fieldyang/index.html"

[[email protected]~]$ ll | grep index

#利用pdsh在远程主机上执行删除命

[[email protected] ~]$pdsh -R ssh -g userhosts "sudo /etc/init.d/httpd start"

slave:正在启动httpd[确定]

#利用pdsh在远程主机上启动某系服务,注意sudo命令需要远程用户启用sudo权限

[[email protected]~]$ pdsh -R ssh -g userhosts "sudo mkdir /mnt/test"

[[email protected]]$ ll | grep test

drwxr-xr-x 2 root root 4096 33011:18 test

#利用pdsh在远程主机上创建目录

7pdsh交互模式:

pdsh交互模式和pdsh命令区别不大,只是把在远程执行的命令放到pdsh命令行下执行

[[email protected]~]$ pdsh -R ssh -w slave.field.com

pdsh>pwd

slave:/home/fieldyang

pdsh>mkdir mysql

pdsh>echo "slave.field.com">hosts

pdsh>cat hosts

slave:slave.field.com

pdsh>ls -l

slave:总用量476

slave:-rw-rw-r-- 1 fieldyang fieldyang 16 33011:28 hosts

slave:drwxrwxr-x 3 fieldyang fieldyang 4096 2132006 iftop-0.17

slave:-rw-r--r-- 1 root root 160381 32910:15 iftop-0.17.tar.gz

slave:drwxrwxr-x 2 fieldyang fieldyang 4096 33011:24 mysql

slave:-rw-r--r-- 1 root root 277707 32910:15 rkhunter-1.4.2.tar.gz

pdsh>ls -l /mnt

slave:总用量125966

slave:drwxrwxrwx 1 1000 users 16384 32115:14 share

slave:drwxr-xr-x 2 root root 4096 33011:18 test

slave:drwxr-xr-x 6 1001 1001 4096 8252016 usr

slave:drwxr-xr-x. 2 root root 4096 6132016 vb

pdsh>sudo tar zxvf /home/fieldyang/rkhunter-1.4.2.tar.gz -C /mnt

slave:rkhunter-1.4.2/

......

slave:rkhunter-1.4.2/installer.sh

pdsh>ls -l /mnt

slave:总用量125970

slave:drwxr-xr-x 3 root root 4096 3132014 rkhunter-1.4.2

slave:drwxrwxrwx 1 1000 users 16384 32115:14 share

slave:drwxr-xr-x 2 root root 4096 33011:18 test

slave:drwxr-xr-x 6 1001 1001 4096 8252016 usr

slave:drwxr-xr-x. 2 root root 4096 6132016 vb

pdsh>

pdsh>quit


四、pdcp应用实例

1将本地主机/home/fieldyang/pssh-2.3.1.tar.gz复制到远程主机的/home/fieldyang目录下

[[email protected]~]$ pdcp -R ssh -g userhosts /home/fieldyang/pssh-2.3.1.tar.gz/home/fieldyang

2将本地主机/home/fieldyang/test下的所有文件和子目录递归复制到远程主机的/home/fieldyang目录下

[[email protected]~]$ pdcp -R ssh -g userhosts -r /home/fieldyang/test /home/fieldyang



以上是关于高性能 HTTP 负载测试工具 Vegeta及并行分布式运维工具pdsh的主要内容,如果未能解决你的问题,请参考以下文章

POST Api 的 Vegeta 负载测试

推荐一款实时图形化分析的性能测试工具

性能测试工具 - Apache JMeter (安装)

HTTP接口性能测试工具详解

windows下Nginx配置及负载均衡使用

测试web性能小工具