Skip to content

Releases: oldthreefeng/stress

v1.1.2

29 Dec 18:42
Compare
Choose a tag to compare

stress

go 实现的压测工具,每个用户用一个协程的方式模拟,最大限度的利用 CPU 资源. 下载

1.1 安装

使用make安装. 建议使用make安装.

$ git clone https://github.com/oldthreefeng/stress
$ make linux

使用golang build

$ git clone https://github.com/oldthreefeng/stress
$ go build -o stress main.go

使用脚本项目脚本构建 build.sh

$ git clone https://github.com/oldthreefeng/stress
$ sh build.sh v1.0.0

1.2 项目体验

参数说明:

-c 表示并发数 默认为 1

-n 每个并发执行请求的次数, 默认为 1 ,总请求的次数 = 并发数 * 每个并发执行请求的次数

-u 需要压测的地址 example: http://www.baidu.com/

# 运行 以linux为示例
./stress -c 1 -n 100 -u https://www.baidu.com/

or use in docker ,高并发建议开启多docker。在性能差的机子上,运行效果不好。

$ docker pull louisehong/stress 
docker run --rm louisehong/stress -c 10 -n 10 -u https://www.baidu.com/ 

 开始启动  并发数:10 请求数:10 请求参数: 
request:
 form:http 
 url:https://www.baidu.com/ 
 method:GET 
 headers:map[] 
 data: 
 verify:statusCode 
 timeout:30s 
 debug:false 



─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────
 耗时│ 并发数│ 成功数│ 失败数│   qps  │最长耗时│最短耗时│平均耗时│ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────
   1s│     10│     99│      0│  176.48│   82.88│   40.26│    5.67│200:99
   2s│     10│    100│      0│  149.89│ 1061.94│   40.26│    6.67│200:100


*************************  结果 stat  ****************************
处理协程数量: 10
请求总数(并发数*请求数 -c * -n): 100 总请求时间: 1.557 秒 successNum: 100 failureNum: 0
*************************  结果 end   ****************************
  • 压测结果展示

执行以后,终端每秒钟都会输出一次结果,压测完成以后输出执行的压测结果

压测结果展示:


─────┬───────┬───────┬───────┬────────┬────────┬────────┬────────┬────────
 耗时│ 并发数 │ 成功数│ 失败数 │   qps  │最长耗时 │最短耗时│平均耗时 │ 错误码
─────┼───────┼───────┼───────┼────────┼────────┼────────┼────────┼────────
   1s│      1│      8│      0│    8.09│  133.16│  110.98│  123.56│200:8
   2s│      1│     15│      0│    8.02│  138.74│  110.98│  124.61│200:15
   3s│      1│     23│      0│    7.80│  220.43│  110.98│  128.18│200:23
   4s│      1│     31│      0│    7.83│  220.43│  110.23│  127.67│200:31
   5s│      1│     39│      0│    7.81│  220.43│  110.23│  128.03│200:39
   6s│      1│     46│      0│    7.72│  220.43│  110.23│  129.59│200:46
   7s│      1│     54│      0│    7.79│  220.43│  110.23│  128.42│200:54
   8s│      1│     62│      0│    7.81│  220.43│  110.23│  128.09│200:62
   9s│      1│     70│      0│    7.79│  220.43│  110.23│  128.33│200:70
  10s│      1│     78│      0│    7.82│  220.43│  106.47│  127.85│200:78
  11s│      1│     84│      0│    7.64│  371.02│  106.47│  130.96│200:84
  12s│      1│     91│      0│    7.63│  371.02│  106.47│  131.02│200:91
  13s│      1│     99│      0│    7.66│  371.02│  106.47│  130.54│200:99
  13s│      1│    100│      0│    7.66│  371.02│  106.47│  130.52│200:100


*************************  结果 stat  ****************************
处理协程数量: 1
请求总数: 100 总请求时间: 13.055 秒 successNum: 100 failureNum: 0
*************************  结果 end   ****************************

参数解释:

耗时: 程序运行耗时。程序每秒钟输出一次压测结果

并发数: 并发数,启动的协程数

成功数: 压测中,请求成功的数量

失败数: 压测中,请求失败的数量

qps: 当前压测的QPS(每秒钟处理请求数量)

最长耗时: 压测中,单个请求最长的响应时长

最短耗时: 压测中,单个请求最短的响应时长

平均耗时: 压测中,单个请求平均的响应时长

错误码: 压测中,接口返回的 code码:返回次数的集合

2.1 压测是什么

压测,即压力测试,是确立系统稳定性的一种测试方法,通常在系统正常运作范围之外进行,以考察其功能极限和隐患。

主要检测服务器的承受能力,包括用户承受能力(多少用户同时玩基本不影响质量)、流量承受等。

  • 压测的目的就是通过压测(模拟真实用户的行为),测算出机器的性能(单台机器的QPS),从而推算出系统在承受指定用户数(100W)时,需要多少机器能支撑得住
  • 压测是在上线前为了应对未来可能达到的用户数量的一次预估(提前演练),压测以后通过优化程序的性能或准备充足的机器,来保证用户的体验。
压测类型 解释
压力测试(Stress Testing) 也称之为强度测试,测试一个系统的最大抗压能力,在强负载(大数据、高并发)的情况下,测试系统所能承受的最大压力,预估系统的瓶颈
并发测试(Concurrency Testing) 通过模拟很多用户同一时刻访问系统或对系统某一个功能进行操作,来测试系统的性能,从中发现问题(并发读写、线程控制、资源争抢)
耐久性测试(Configuration Testing) 通过对系统在大负荷的条件下长时间运行,测试系统、机器的长时间运行下的状况,从中发现问题(内存泄漏、数据库连接池不释放、资源不回收)

2.2 如何计算压测指标

  • 压测我们需要有目的性的压测,这次压测我们需要达到什么目标(如:单台机器的性能为 100QPS?网站能同时满足100W人同时在线)

  • 可以通过以下计算方法来进行计算:

  • 压测原则:每天80%的访问量集中在20%的时间里,这20%的时间就叫做峰值

  • 公式: ( 总PV数*80% ) / ( 每天的秒数*20% ) = 峰值时间每秒钟请求数(QPS)

  • 机器: 峰值时间每秒钟请求数(QPS) / 单台机器的QPS = 需要的机器的数量

  • 假设:网站每天的用户数(100W),每天的用户的访问量约为3000W PV,这台机器的需要多少QPS?

( 30000000*0.8 ) / (86400 * 0.2) ≈ 1389 (QPS)

3.1 用法

$ ./stress -h
stress is a test cli for http and websocket stress written by golang, 
go 实现的压测工具,每个用户用一个协程的方式模拟,最大限度的利用 CPU 资源

Usage:
  stress [flags]
  stress [command]

Examples:
        
        # stress curl file to test 
        stress -f utils/curl.txt

        # stress curl file read from stdin 
        cat utils/curl.txt | stress -f -

        # stress concurrency 10 & 10 times
        stress -c 10 -n 10 -f  utils/curl.txt

        # stress cli url
        stress -c 10 -n 100 -u https://www.baidu.com


Available Commands:
  help        Help about any command
  version     stress version

Flags:
  -c, --concurrency uint    并发数 (default 1)
      --config string       config file for stress (default is $HOME/.stress.yaml)
      --data string         http post data
  -d, --debug               debug 模式
  -H, --header strings      http headers
  -h, --help                help for stress
  -n, --number uint         单协程的请求数 (default 1)
  -f, --path string         read curl file to build test
  -u, --requestUrl string   curl文件路径
  -t, --toggle              Help message for toggle
  -v, --verify string        verify 验证方法 在server/verify中 http 支持:statusCode、json webSocket支持:json (default "statusCode")

Use "stress [command] --help" for more information about a command.
  • 使用 curl文件进行压测

curl是Linux在命令行下的工作的文件传输工具,是一款很强大的http命令行工具。

使用curl文件可以压测使用非GET的请求,支持设置http请求的 method、cookies、header、body等参数

I: chrome 浏览器生成 curl文件,打开开发者模式(快捷键F12),如图所示,生成 curl 在终端执行命令
chrome cURL

II: postman 生成 curl 命令
postman cURL

生成内容粘贴到项目目录下的utils/curl.txt文件中,执行下面命令就可以从curl.txt文件中读取需要压测的内容进行压测了

  • 支持多步压力测试

目前使用的方法是按行来分割每个请求.

$ cat utils/curl.txt
curl 'https://mall.youpenglai.com/apis/version' -H 'User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Language: zh-CN,en-US;q=0.7,en;q=0.3' --compressed -H 'Connection: keep-alive' -H 'Upgrade-Insecure-Requests: 1' -H 'Cache-Control: max-age=0' -H 'TE: Trailers'
curl 'https://www.youpenglai.com/v2/sys/server' -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8' -H 'Accept-Language: zh-CN,en-US;q=0.7,en;q=0.3' --compressed -H 'Connection: keep-alive' -H 'Cookie: _ga=GA1.2.462595907.1596072242; Hm_lvt_16789552d8e4ee2108c29cc8197bfe19=1596077258; _gid=GA1.2.1014297080.1596441772; JSESSIONID=88EE56D0223D34DD83EB301962B121D1' -H 'Upgrade-Insecure-Requests: 1' -H 'Cache-Control: max-age=0'

支持从stdin读取curl请求. 从stdin读取的内容会保存在/tmp/curl.tmp

$ cat utils/curl.txt  | ./stress -f -

命令行示例.

$ ./stress -c 1 -n 1 -d -u 'https://page.aliyun.com/delivery/plan/list' \
  -H 'authority: page.aliyun.com' \
  -H 'accept: application/json, text/plain, */*' \
  -H 'content-type: application/x-www-form-urlencoded' \
  -H 'origin: https://cn.aliyun.com' \
  -H 'sec-fetch-site: same-site' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-dest: empty' \
  -H 'referer: https://cn.aliyun.com/' \
  -H 'accept-language: zh-CN,zh;q=0.9' \
  -H 'cookie: aliyun_choice=CN; JSESSIONID=J8866281-CKCFJ4BUZ7GDO9V89YBW1-KJ3J5V9K-GYUW7; maliyun_temporary_console0=1AbLByOMHeZe3G41KYd5WWZvrM%2BGErkaLcWfBbgveKA9ifboArprPASvFUUfhwHtt44qsDwVqMk8Wkdr1F5LccYk2mPCZJiXb0q%2Bllj5u3SQGQurtyPqnG489y%2FkoA%2FEvOwsXJTvXTFQPK%2BGJD4FJg%3D%3D; cna=L3Q5F8cHDGgCAXL3r8fEZtdU; isg=BFNThsmSCcgX-sUcc5Jo2s2T4tF9COfKYi8g9wVwr3KphHMmjdh3GrHFvPTqJD_C; l=eBaceXLnQGBjstRJBOfwPurza77OSIRAguPzaNbMiT5POw1B5WAlWZbqyNY6C3GVh6lwR37EODnaBeYBc3K-nxvOu9eFfGMmn' \
  --data 'adPlanQueryParam=%7B%22adZone%22%3A%7B%22positionList%22%3A%5B%7B%22positionId%22%3A83%7D%5D%7D%2C%22requestId%22%3A%2217958651-f205-44c7-ad5d-f8af92a6217a%22%7D' \
  --compressed

like curl cmd , use --data-raw is the same with --data, when use --compressed, only support command line and gzip.
for curl file. the Header is in it. use --compressed, just do this req.Header.Add("Accept-Encoding", "gzip").

$ ./stress -c 1 -n 1 -d -u 'https://page.aliyun.com/delivery/plan/list' \
  -H 'authority: page.aliyun.com' \
  -H 'accept: application/json, text/plain, */*' \
  -H 'content-type: application/x-www-form-urlencoded' \
  -H 'origin: https://cn.aliyun.com' \
  -H 'sec-fetch-site: same-site' \
  -H 'sec-fetch-mode: cors' \
  -H 'sec-fetch-dest: empty' \
  -H 'referer: https://cn.aliyun.com/' \
  -H 'accept-language: zh-CN,zh;q=0.9' \
  -H 'cookie: aliyun_choice=CN; JSESSIONID=J8866281-CKCFJ4BUZ7GDO9V89YBW1-KJ3J5V9K-GYUW7; maliyun_temporary_console0=1AbLByOMHeZe3G41KYd5WWZvrM%2BGErkaLcWfBbgveKA9ifboArprPASvFUUfhwHtt44qsDwVqMk8Wkdr1F5LccYk2mPCZJiXb0q%2Bllj5u3SQGQurtyPqnG489y%2FkoA%2FEvOwsXJTvXTFQPK%2BGJD4FJg%3D%3D; cna=L3Q5F8cHDGgCAXL3r8fEZtdU; isg=BFNThsmSCcgX-sUcc5Jo2s2T4tF9COfKYi8g9wVwr3KphHMmjdh3GrHFvPTqJD_C; l=eBaceXLnQGBjstRJBOfwPurza77OSIRAguPzaNbMiT5POw1B5WAlWZbqyNY6C3GVh6lwR37EODnaBeYBc3K-nxvOu9eFfGMmn' \
  --data-raw 'adPlanQueryParam=%7B%22adZone%22%3A%7B%22positionList%22%3A%5B%7B%22positionId%22%3A83%7D%5D%7D%2C%22requestId%22%3A%2217958651-f205-44c7-ad5d-f8af92a6217a%22%7D' \
  --compressed

Docker Use

$ docker pull louisehong/stress

$ docker run --rm   louisehong/stress  -c 1 -n 1 -d -u 'https://page.aliyun.com/delivery/plan/list' \
  -H 'authority: page.aliyun.com' \
  -H 'accept: application/json, text/plain, */*' \
  -H 'content-type: application/x-www-form-urlencoded' \
  -H 'origin: https://cn.aliyun.com' ...
Read more

v1.1.1

18 Aug 10:35
Compare
Choose a tag to compare

Changelog

eab50da add verify for huohua api
e96f655 fix panic: runtime error: integer divide by zero
6597383 fix syntax error
f5e274e when curls in file wc -l curl.txt more then 100, Concurrency is len(list), default http method is to slow.

Docker images

  • docker pull louisehong/stress:latest
  • docker pull louisehong/stress:v1.1.1

v1.1.0

14 Aug 03:10
Compare
Choose a tag to compare

Changelog

b3144a3 add docker use in reademe
efc8874 add travis
385b2a9 fix print of concurren status
2ba4cfc fix readme
ad1e5c8 gofmt
1016792 golint
6b38489 golint
2664ce1 use comcurrentMap to aviod fatal err write map
40f51ce use concurrent map to solve fatal error: concurrent map writes #8

Docker images

  • docker pull louisehong/stress:latest
  • docker pull louisehong/stress:v1.1.0

v1.0.3

06 Aug 17:03
Compare
Choose a tag to compare

Changelog

b94f2a6 support cli ,--data-raw, --compressed , change the path stucture.
f8139c3 Merge pull request #1 from oldthreefeng/develop
dcbb478 Merge pull request #2 from oldthreefeng/develop
617e063 Merge pull request #3 from oldthreefeng/develop
b14b114 Merge pull request #4 from oldthreefeng/develop
dfae761 Merge pull request #5 from oldthreefeng/develop
b90f27d Merge pull request #6 from oldthreefeng/develop
284ee18 Merge pull request #7 from oldthreefeng/develop
d00ad34 add makefile
327311c add parse curl file
41ff9bb add readme
7c0b3e1 fix build by
09ade5f fix curl multi line for link
a9fad7d fix gitignore
c57bd7e fix help
a8f5c47 fix read curl file with no debug mode
dd85098 fix version
31c2c4e init
7a2f0a5 init commit
68a65e5 origin implementation function
01a12ab remove curl cmd
21c4bb7 support stdin input
73a5caa test for docker
7003faa test for docker

Docker images

  • docker pull louisehong/stress:latest
  • docker pull louisehong/stress:v1.0.3

v1.0.1

06 Aug 12:24
Compare
Choose a tag to compare

Changelog

8da8236 fix build by
70e423e fix version
31a0566 test for docker
73a5caa test for docker

Docker images

  • docker pull louisehong/stress:latest
  • docker pull louisehong/stress:v1.0.1