Hey 压力测试工具完整使用指南

Hey 压力测试工具完整使用指南

Hey(原名为 Boom)是用 Go 语言编写的现代化 HTTP 负载测试工具,性能比 Apache Bench 更好。

1. 安装 Hey

在 Windows 上安装

# 方法1:使用 Scoop

scoop install hey

# 方法2:下载二进制文件

# 访问:https://github.com/rakyll/hey/releases

# 下载 hey_windows_amd64.exe,重命名为 hey.exe,添加到 PATH

# 方法3:通过 Go 安装

go install github.com/rakyll/hey@latest

# 然后确保 GOPATH/bin 在 PATH 中

在 macOS 上安装

# 使用 Homebrew

brew install hey

# 或通过 Go

go install github.com/rakyll/hey@latest

在 Linux 上安装

# Ubuntu/Debian

sudo apt-get update

sudo apt-get install hey

# 或通过 Go

go install github.com/rakyll/hey@latest

2. 基本用法

快速开始

# 基本 GET 请求测试

hey https://example.com

# 设置并发数和请求数

hey -n 1000 -c 50 https://example.com

基本参数

# 指定总请求数

hey -n 2000 https://api.example.com

# 指定并发数(同时进行的请求数)

hey -c 100 https://api.example.com

# 指定测试持续时间

hey -z 30s https://api.example.com # 30秒

hey -z 5m https://api.example.com # 5分钟

hey -z 2h https://api.example.com # 2小时

# 组合使用

hey -n 10000 -c 200 -z 1m https://api.example.com

3. 常用参数详解

负载参数

# 并发控制

-c 100 # 100个并发worker

-n 10000 # 总共10000个请求

-z 30s # 持续30秒

-q 100 # 限制每个worker每秒100个请求

# 如果同时指定-n和-z,以先达到的为准

hey -n 1000 -z 10s https://example.com

HTTP 方法控制

# 指定 HTTP 方法

-m GET # GET请求(默认)

-m POST # POST请求

-m PUT # PUT请求

-m DELETE # DELETE请求

-m PATCH # PATCH请求

hey -m POST https://api.example.com/users

请求头和内容

# 自定义请求头

-H "Content-Type: application/json"

-H "Authorization: Bearer token123"

-H "User-Agent: MyLoadTest/1.0"

# 多个请求头

hey -H "Accept: application/json" \

-H "X-API-Key: mykey" \

https://api.example.com/data

# POST 数据

-d '{"name":"John","age":30}'

-d "username=admin&password=123456"

# 从文件读取请求体

-D data.json

-D post_data.txt

# Content-Type

-T "application/json"

-T "application/x-www-form-urlencoded"

超时和重试

# 超时设置

-t 10 # 每个请求10秒超时

-t 0 # 无超时

# 禁用 keep-alive

-disable-keepalive

# 禁用压缩

-disable-compression

# 主机头覆盖

-host "api.example.com"

# 代理设置

-x http://proxy:8080

4. 实战示例

示例1:基本网站压力测试

# 测试网站首页

hey -z 30s -c 100 https://example.com

# 详细输出

hey -z 30s -c 100 -m GET -t 5 \

-H "Accept: text/html" \

https://example.com

示例2:REST API 测试

# GET 请求测试

hey -z 1m -c 50 -m GET \

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \

-H "Accept: application/json" \

https://api.example.com/users

# POST JSON 数据

hey -z 1m -c 20 -m POST \

-H "Content-Type: application/json" \

-H "Authorization: Bearer token123" \

-d '{"name":"test","email":"test@example.com"}' \

https://api.example.com/users

# PUT 请求

hey -n 1000 -c 10 -m PUT \

-H "Content-Type: application/json" \

-d '{"status":"active"}' \

https://api.example.com/users/123

示例3:登录接口测试

# 表单登录

hey -z 2m -c 20 -m POST \

-H "Content-Type: application/x-www-form-urlencoded" \

-d "username=testuser&password=testpass" \

https://api.example.com/login

# JSON 登录

hey -z 2m -c 20 -m POST \

-H "Content-Type: application/json" \

-d '{"username":"test","password":"123456"}' \

https://api.example.com/auth/login

示例4:文件上传测试

# 使用 -D 从文件读取 multipart 数据

# 首先创建 multipart 数据文件

echo '--boundary

Content-Disposition: form-data; name="file"; filename="test.jpg"

Content-Type: image/jpeg

[文件内容,这里可以使用二进制]

--boundary--

' > upload_data.txt

# 然后测试

hey -z 1m -c 5 -m POST \

-H "Content-Type: multipart/form-data; boundary=boundary" \

-D upload_data.txt \

https://api.example.com/upload

示例5:查询参数测试

# 带查询参数的 GET

hey -z 30s -c 50 \

"https://api.example.com/search?q=golang&page=1&limit=20"

# 多个查询参数

hey -z 30s -c 50 \

"https://api.example.com/products?category=electronics&min_price=100&max_price=1000&sort=price_desc"

5. 高级用法

读取 URL 列表文件

# 创建 URL 文件

cat > urls.txt << EOF

https://api.example.com/users/1

https://api.example.com/users/2

https://api.example.com/users/3

https://api.example.com/products/1

https://api.example.com/products/2

EOF

# 从文件读取 URL

hey -z 1m -c 10 -m GET < urls.txt

输出结果到文件

# 保存输出到文件

hey -z 1m -c 50 https://example.com > result.txt

# 只保存摘要信息

hey -z 1m -c 50 https://example.com 2>&1 | tee result.txt

使用自定义 DNS

# 指定 DNS 服务器

hey -z 30s -c 20 \

-host "api.example.com:8.8.8.8" \

https://api.example.com/api

6. 实战场景案例

场景1:电商网站压力测试

# 首页访问

hey -z 5m -c 200 -q 50 \

-H "Accept: text/html,application/xhtml+xml" \

-H "Accept-Language: zh-CN,zh;q=0.9" \

https://shop.example.com

# 商品列表页

hey -z 3m -c 100 -q 30 \

"https://shop.example.com/products?category=electronics&page=1"

# 商品详情页

hey -z 2m -c 50 \

-H "Referer: https://shop.example.com/products" \

https://shop.example.com/product/123

# 下单接口

hey -z 1m -c 20 -m POST \

-H "Content-Type: application/json" \

-H "Authorization: Bearer user_token" \

-d '{"product_id":123,"quantity":1,"address_id":456}' \

https://api.shop.example.com/orders

场景2:API 网关测试

# 测试多个端点

#!/bin/bash

ENDPOINTS=(

"/api/v1/users"

"/api/v1/products"

"/api/v1/orders"

"/api/v1/payments"

)

BASE_URL="https://api.example.com"

for endpoint in "${ENDPOINTS[@]}"; do

echo "Testing: ${BASE_URL}${endpoint}"

hey -z 30s -c 50 "${BASE_URL}${endpoint}"

echo "====================================="

sleep 5

done

场景3:微服务链路测试

# 模拟完整用户流程

# 1. 用户登录

hey -n 1000 -c 20 -m POST \

-H "Content-Type: application/json" \

-d '{"username":"test","password":"password"}' \

https://auth.example.com/login

# 2. 获取用户信息

hey -n 2000 -c 50 -m GET \

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \

https://user.example.com/profile

# 3. 浏览商品

hey -n 5000 -c 100 -m GET \

https://product.example.com/items?page=1&size=20

# 4. 添加到购物车

hey -n 2000 -c 30 -m POST \

-H "Content-Type: application/json" \

-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \

-d '{"item_id":123,"quantity":2}' \

https://cart.example.com/add

7. 输出结果解读

运行测试后的输出示例:

Summary:

Total: 10.0024 secs

Slowest: 2.1234 secs

Fastest: 0.0123 secs

Average: 0.4567 secs

Requests/sec: 499.88

Total data: 1.23 MB

Size/request: 1234 bytes

Response time histogram:

0.012 [1] |

0.223 [250] |∎∎∎∎∎∎∎∎∎∎

0.433 [500] |∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎∎

0.644 [200] |∎∎∎∎∎∎∎∎

0.855 [30] |∎

1.066 [10] |

1.277 [5] |

1.488 [3] |

1.699 [1] |

1.910 [0] |

2.121 [1] |

Latency distribution:

10% in 0.1234 secs

25% in 0.2345 secs

50% in 0.3456 secs

75% in 0.5678 secs

90% in 0.7890 secs

95% in 1.1234 secs

99% in 1.9876 secs

Details (average, fastest, slowest):

DNS+dialup: 0.0012 secs, 0.0001 secs, 0.0123 secs

DNS-lookup: 0.0005 secs, 0.0000 secs, 0.0056 secs

req write: 0.0001 secs, 0.0000 secs, 0.0012 secs

resp wait: 0.3456 secs, 0.0101 secs, 1.9876 secs

resp read: 0.0002 secs, 0.0000 secs, 0.0023 secs

Status code distribution:

[200] 1000 responses

关键指标解读:

Requests/sec:QPS,系统吞吐量

Average:平均响应时间

p50/p95/p99:分位响应时间

Latency distribution:延迟分布

Status code:HTTP 状态码分布

8. 最佳实践

渐进式压力测试

#!/bin/bash

# 渐进增加并发数

for concurrent in 10 50 100 200 500 1000; do

echo "测试并发数: ${concurrent}"

hey -z 30s -c ${concurrent} https://api.example.com

echo "等待10秒进行下一轮测试..."

sleep 10

done

带思考时间的测试

#!/bin/bash

# 模拟用户行为,间隔1秒

for i in {1..1000}; do

# 每次请求间隔1秒

hey -n 1 -c 1 https://api.example.com/api/endpoint

sleep 1

done

混合场景测试

#!/bin/bash

# 混合不同比例的请求

while true; do

# 80% GET请求

for i in {1..8}; do

hey -n 1 -c 1 https://api.example.com/get-endpoint &

done

# 15% POST请求

for i in {1..1}; do

hey -n 1 -c 1 -m POST \

-H "Content-Type: application/json" \

-d '{"action":"update"}' \

https://api.example.com/post-endpoint &

done

# 5% DELETE请求

hey -n 1 -c 1 -m DELETE \

https://api.example.com/delete-endpoint &

wait

sleep 0.1

done

9. 问题诊断

常见错误及解决

# 1. 连接被拒绝

# 检查服务是否启动

netstat -an | grep :8080

# 2. 太多打开文件

# Linux/Mac: 增加文件描述符限制

ulimit -n 100000

# 3. 端口耗尽

# 减少并发数

hey -c 1000 ... # 而不是 20000

# 4. DNS 解析问题

# 使用 -host 指定 IP

hey -host "api.example.com:1.2.3.4" https://api.example.com

调试输出

# 显示详细调试信息

hey -v -z 10s -c 10 https://example.com

# 跟踪重定向

hey -disable-redirects -z 10s -c 10 https://example.com

10. 与监控工具结合

实时监控脚本

#!/bin/bash

# 持续监控 API 性能

while true; do

timestamp=$(date +"%Y-%m-%d %H:%M:%S")

echo "======= ${timestamp} ======="

result=$(hey -z 5s -c 50 https://api.example.com/health 2>&1 | grep "Requests/sec")

qps=$(echo $result | awk '{print $2}')

echo "当前 QPS: ${qps}"

if (( $(echo "$qps < 100" | bc -l) )); then

echo "警告: QPS 低于 100"

fi

sleep 60

done

生成测试报告

#!/bin/bash

# 生成 HTML 报告

echo "

压力测试报告

" > report.html

for endpoint in "/api/users" "/api/products" "/api/orders"; do

echo "

测试端点: ${endpoint}

" >> report.html

echo "

" >> report.html

hey -z 30s -c 100 "https://api.example.com${endpoint}" 2>&1 >> report.html

echo "


" >> report.html

done

echo "" >> report.html

11. 与其他工具比较

工具优点缺点hey​安装简单,结果清晰,支持持续测试功能相对基础ab​Apache 自带,历史悠久不支持持续测试,结果不如 hey 详细wrk​性能极高,支持 Lua 脚本安装稍复杂,不支持 Windows 原生vegeta​功能强大,支持各种输出格式配置稍复杂k6​现代化,支持 JavaScript 脚本需要学习脚本语法

12. 实际工作流示例

完整的压力测试流程

#!/bin/bash

# 完整的 API 压力测试流程

echo "1. 预热阶段 (10% 负载)"

hey -z 30s -c 20 https://api.example.com

echo "等待 30 秒..."

sleep 30

echo "2. 中等负载阶段 (50% 负载)"

hey -z 2m -c 100 https://api.example.com

echo "等待 60 秒..."

sleep 60

echo "3. 峰值负载阶段 (100% 负载)"

hey -z 3m -c 200 https://api.example.com

echo "4. 稳定性测试 (80% 负载持续 5 分钟)"

hey -z 5m -c 160 https://api.example.com

echo "5. 恢复测试 (负载逐步降低)"

for concurrent in 160 120 80 40 20 10; do

echo "并发数: ${concurrent}"

hey -z 1m -c ${concurrent} https://api.example.com

done

echo "压力测试完成!"

通过这个完整指南,您可以全面掌握 hey 工具的使用,从基本测试到复杂的生产环境压力测试场景。