关于IT运维技术的
最佳实践博客网站

高性能 HTTP 负载测试工具:Vegeta

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

Usage: vegeta [global flags] <command> [command flags]

global flags:
  -cpus int
    	使用CUP的数量 (默认 4 个)
  -profile string
    	Enable profiling of [cpu, heap]
  -version
    	打印版本并退出

attack command:
  -body string
    	请求的主体文件
  -cert string
    	TLS客户PEM编码的证书文件
  -connections int
    	没个目标主机最大打开闲置链接数 (默认 10000)
  -duration duration
    	持续攻击时间 [0 = forever]
  -header value
    	请求头
  -insecure
    	忽略无效的服务器TLS证书
  -keepalive
    	使用持久链接 (default true)
  -key string
    	TLS客户端PEM编码的私钥文件
  -laddr value
    	本地IP地址 (default 0.0.0.0)
  -lazy
    	延迟懒散的读取目标
  -output string
    	输出文件 (default "stdout")
  -rate uint
    	每秒请求数 (default 50)
  -redirects int
    	遵循重定向的次数. -1 不会遵循重定向但会标记为成功 (默认 10)
  -root-certs value
    	TLS根证书文件 (逗号分隔列表)
  -targets string
    	目标文件 (default "stdin")
  -timeout duration
    	请求超时时间 (default 30s)
  -workers uint
    	初始化进程数 (default 10)

report command:
  -inputs string
    	输入文件 (comma separated) (default "stdin")
  -output string
    	输出文件 (default "stdout")
  -reporter string
    	表报字符格式 [text, json, plot, hist[buckets]] (default "text")

dump command:
  -dumper string
    	Dumper [json, csv] (default "json")
  -inputs string
    	Input files (comma separated) (default "stdin")
  -output string
    	Output file (default "stdout")

举例:
  echo "GET http://localhost/" | vegeta attack -duration=5s | tee results.bin | vegeta report
  vegeta attack -targets=targets.txt > results.bin
  vegeta report -inputs=results.bin -reporter=json > metrics.json
  cat results.bin | vegeta report -reporter=plot > plot.html
  cat results.bin | vegeta report -reporter="hist[0,100ms,200ms,300ms]"

-cpus

指定使用CPU的个数. 默认为系统中可用的CPU数。

-profile

指定扫描器在执行期间. cpu and heap 两者配置文件支持. 默认为空.

-version

打印版本并退出.

attack

 ~/ vegeta attack -h
Usage of vegeta attack:
  -body string
    	请求主体文件
  -cert string
    	TLS客户PEM编码的证书文件
  -connections int
    	每个目标主机最大打开闲置链接数 (default 10000)
  -duration duration
    	持续攻击时间 [0 = forever]
  -header value
    	请求头
  -insecure
    	忽略无效的服务器TLS证书
  -keepalive
    	使用持久链接 (default true)
  -key string
    	TLS客户端PEM编码的私钥文件
  -laddr value
    	本地IP地址 (default 0.0.0.0)
  -lazy
    	延迟懒散的读取目标
  -output string
    	输出文件 (default "stdout")
  -rate uint
    	每秒请求数 (default 50)
  -redirects int
    	遵循重定向的次数. -1 不会遵循重定向但会标记为成功 (默认 10)
  -root-certs value
    	TLS根证书文件 (逗号分隔列表)
  -targets string
    	目标文件 (default "stdin")
  -timeout duration
    	请求超时时间 (default 30s)
  -workers uint
    	初始化进程数 (default 10)

-body

指定文件里的内容,将被设置为请求主体去攻击目标, 查看 -targets 参数.

-cert

指定PEM编码和TLS客户端证书文件用于HTTPS的请求。如果-key未指定,它会被设置为这个标志的值

-connections

指定每个目标主机打开的空闲连接的最大数目。

-duration

指定发送请求到目标主机需要多长时间. 内部结构的并发性的设置有这个值作为一个变量. 测试的实际运行时间可能比设定的时间要长,由于响应有延迟. 用0表示无限攻击.

-header

指定定义目标的请求头, 查看 -targets. 根据需要,可以重复指定多个请求标记。

-http2

指定是否启用HTTP/2请求支持它的服务器。

-insecure

指定是否忽略无效的服务器TLS证书。

-keepalive

指定是否重新使用HTTP请求之间的TCP连接。

-key

指定要使用HTTPS请求中使用的PEM编码SSL客户端证书私钥文件。

-laddr

指定要使用的本地IP地址。

-lazy

指定是否懒惰,而不是急切地读取输入的目标。这使得流指标纳入攻击指令,并减少内存占用。权衡是针对每个目标命中增加延迟之一。

-output

指定的输出文件结果将被写入二进制. 使用管道将报告命令输入. 默认为标准输出.

-rate

指定每秒钟对目标发送请求的速率,实际的请求率可能因为喜欢搜集的垃圾稍微有不同, 但总体来说它应该保持非常接近指定的速率.

-redirects

指定每个请求的重定向的最大次数. 默认为 10 次. 当值为 -1, 重定向不会遵循但响应标记为成功.

-root-certs

指定可信的TLS 根CAs 证书文件,可用逗号分隔列表. 如果未指定,系统默认的CA证书将被使用。

-targets

指定一个行分隔文件中的攻击目标. 格式应该如下:

简单目标

GET http://goku:9090/path/to/dragon?item=balls
GET http://user:password@goku:9090/path/to
HEAD http://goku:9090/path/to/success

自定义请求头的目标

GET http://user:password@goku:9090/path/to
X-Account-ID: 8675309

DELETE http://goku:9090/path/to/remove
Confirmation-Token: 90215
Authorization: Token DEADBEEF

自定义请求的主体

POST http://goku:9090/things
@/path/to/newthing.json

PATCH http://goku:9090/thing/71988591
@/path/to/thing-71988591.json

自定义请求头和请求主体

POST http://goku:9090/things
X-Account-ID: 99
@/path/to/newthing.json

-timeout

指定每个请求的超时时间. 默认值为0,禁止超时.

-workers

指定在攻击中使用进程的初始化数量. 进程的实际数量将为了维持所要求的速率,如果有必要可以增加。

report

$ vegeta report -h
Usage of vegeta report:
  -inputs string
      输入文件 (comma separated) (默认 "stdin")
  -output string
      输出文件 (default "stdout")
  -reporter string
      报告格式 [text, json, plot, hist[buckets]] (默认 "text")

-inputs

指定输入文件生成的报告,默认为标准输入. 这些都是 vegeta 攻击的输出内容. 你可以指定多个输出(逗号分隔),它将正在把这些报告进行合并和分类.

-output

指定该报告输出的文件

-reporter

指定要生成的报告类型. 默认为 文本.

text
Requests      [total, rate]             1200, 120.00
Duration      [total, attack, wait]     10.094965987s, 9.949883921s, 145.082066ms
Latencies     [mean, 50, 95, 99, max]   113.172398ms, 108.272568ms, 140.18235ms, 247.771566ms, 264.815246ms
Bytes In      [total, mean]             3714690, 3095.57
Bytes Out     [total, mean]             0, 0.00
Success       [ratio]                   55.42%
Status Codes  [code:count]              0:535  200:665
Error Set:
Get http://localhost:6060: dial tcp 127.0.0.1:6060: connection refused
Get http://localhost:6060: read tcp 127.0.0.1:6060: connection reset by peer
Get http://localhost:6060: dial tcp 127.0.0.1:6060: connection reset by peer
Get http://localhost:6060: write tcp 127.0.0.1:6060: broken pipe
Get http://localhost:6060: net/http: transport closed before response was received
Get http://localhost:6060: http: can't write HTTP request on broken connection

json

{
  "latencies": {
    "total": 237119463,
    "mean": 2371194,
    "50th": 2854306,
    "95th": 3478629,
    "99th": 3530000,
    "max": 3660505
  },
  "bytes_in": {
    "total": 606700,
    "mean": 6067
  },
  "bytes_out": {
    "total": 0,
    "mean": 0
  },
  "earliest": "2015-09-19T14:45:50.645818631+02:00",
  "latest": "2015-09-19T14:45:51.635818575+02:00",
  "end": "2015-09-19T14:45:51.639325797+02:00",
  "duration": 989999944,
  "wait": 3507222,
  "requests": 100,
  "rate": 101.01010672380401,
  "success": 1,
  "status_codes": {
    "200": 100
  },
  "errors": []
}

plot

Dygraphs 上生成一个可以交互式的HTML5基础页面。单击并拖动来选择放大某个区域. 双击缩小. 输入左下角的字段的数字来改变窗口的大小(数据颗粒度)。

在图上每个点的显示表示一次请求, X轴表示请求,Y轴表示请求开始到完成的时间。

plot

hist

计算并打印一个基于文本的直方图. Each bucket upper bound is non-inclusive.

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%  ###################

dump

$ vegeta dump -h
Usage of vegeta dump:
  -dumper string
      Dumper [json, csv] (default "json")
  -inputs string
      Input files (comma separated) (default "stdin")
  -output string
      Output file (default "stdout")

-inputs

指定要转储含有攻击结果的输入文件. 你可以指定多个 (逗号分隔).

-output

指定把转储文件写入到输出文件中.

-dumper

指定转储格式

json

转储攻击结果为json对象

csv

转储6列包含攻击结果的CSV记录. 列包含: unix时间戳, http状态码, NS请求延迟, 字节输出, 字节输入, 和错误。

Usage: Distributed attacks(分布式攻击)

当进行负载测试时,不能因Vegeta自身机器的性能瓶颈限制无法达到预期结果,例如打开的文件数,内存大小, CPU 和 网络带宽, 分布式的使用Vegeta是非常好的想法。

假设场景:攻击速率为每秒69K的请求,假设有3台机器安装了Vegeta.

确保 打开文件描述 和 进程限制设置得高一些,你可以在你的机器上使用 ulimit 命令.

我们已准备好开始攻击(压力测试). 我们需要做的是在每个机器上执行设定的攻击速率和攻击数量,在这里我们使用 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'

前面的命令完成后,就可以将收集到的结果文件在我们的报表中使用

$ for machine in "10.0.1.1 10.0.2.1 10.0.3.1"; do
    scp $machine:~/result.bin $machine.bin &
  done

这个 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:

Usage (Library)

package main

import (
  "fmt"
  "time"

  vegeta "github.com/tsenart/vegeta/lib"
)

func main() {
  rate := uint64(100) // per second
  duration := 4 * time.Second
  targeter := vegeta.NewStaticTargeter(vegeta.Target{
    Method: "GET",
    URL:    "http://localhost:9100/",
  })
  attacker := vegeta.NewAttacker()

  var metrics vegeta.Metrics
  for res := range attacker.Attack(targeter, rate, duration) {
    metrics.Add(res)
  }
  metrics.Close()

  fmt.Printf("99th percentile: %s\n", metrics.Latencies.P99)
}

Limitations(限制)

There will be an upper bound of the supported rate which varies on the machine being used. You could be CPU bound (unlikely), memory bound (more likely) or have system resource limits being reached which ought to be tuned for the process execution. The important limits for us are file descriptors and processes. On a UNIX system you can get and set the current soft-limit values for a user.

$ ulimit -n # file descriptors
2560
$ ulimit -u # processes / threads
709

Just pass a new number as the argument to change it.

赞(1)
未经允许不得转载:菜鸟HOW站长 » 高性能 HTTP 负载测试工具:Vegeta

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址