golang高性能API负载测试与批量任务处理插件Blast的使用
Golang高性能API负载测试与批量任务处理插件Blast的使用
Blast简介
Blast是一个高性能的Golang工具,主要用于:
- 以固定速率发送API请求
- 并发工作者数量可配置
- 执行期间可交互式调整速率
- 协议无关,轻松添加新的工作者类型
- 负载测试:可以向API请求添加随机数据
- 批量任务处理:可以从本地文件或GCS存储桶加载CSV数据,并跳过先前运行中的成功项
安装
Mac
brew tap dave/blast
brew install blast
Linux
查看发布页面获取安装包
从源码安装
go get -u github.com/dave/blast
使用示例
使用dummy工作者以20,000请求/秒的速度发送请求
blast --rate=20000 --workers=1000 --worker-type="dummy" --worker-template='{"min":25,"max":50}'
使用http工作者以1请求/秒的速度请求Google主页
blast --rate=1 --worker-type="http" --payload-template='{"method":"GET","url":"http://www.google.com/"}'
状态监控
Blast每十秒打印一次摘要。运行时可以:
- 按Enter键查看最新状态
- 输入数字调整发送速率
示例输出:
Metrics
=======
Concurrency: 1999 / 2000 workers in use
Desired rate: (all) 10000 1000 100
Actual rate: 2112 5354 989 100
Avg concurrency: 1733 1976 367 37
Duration: 00:40 00:12 00:14 00:12
Total
-----
Started: 84525 69004 14249 1272
Finished: 82525 67004 14249 1272
Mean: 376.0 ms 374.8 ms 379.3 ms 377.9 ms
95th: 491.1 ms 488.1 ms 488.2 ms 489.6 ms
200
---
Count: 79208 (96%) 64320 (96%) 13663 (96%) 1225 (96%)
Mean: 376.2 ms 381.9 ms 374.7 ms 378.1 ms
95th: 487.6 ms 489.0 ms 487.2 ms 490.5 ms
404
---
Count: 2467 (3%) 2002 (3%) 430 (3%) 35 (3%)
Mean: 371.4 ms 371.0 ms 377.2 ms 358.9 ms
95th: 487.1 ms 487.1 ms 486.0 ms 480.4 ms
500
---
Count: 853 (1%) 685 (1%) 156 (1%) 12 (1%)
Mean: 371.2 ms 370.4 ms 374.5 ms 374.3 ms
95th: 487.6 ms 487.1 ms 488.2 ms 466.3 ms
Current rate is 10000 requests / second. Enter a new rate or press enter to view status.
Rate?
配置
Blast可以通过配置文件、命令行标志或环境变量进行配置。--config
标志指定要加载的配置文件,可以是json
、yaml
、toml
或任何Viper支持的格式。
环境变量和命令行标志会覆盖配置文件选项。环境变量需大写并加上"BLAST"前缀,例如BLAST_PAYLOAD_TEMPLATE
。
模板
payload-template
和worker-template
选项使用Go的text/template系统渲染。变量形式如{{ .name }}
或{{ "name" }}
会被数据替换。
还提供了一些简单的函数来注入随机数据,这对负载测试场景很有用:
{{ rand_int -5 5 }}
- -5到5之间的随机整数{{ rand_float -5 5 }}
- -5到5之间的随机浮点数{{ rand_string 10 }}
- 长度为10的随机字符串
工作者
Worker是一个接口,允许Blast轻松扩展以支持任何协议。Worker还可以选择性地实现Starter和Stopper接口来提供初始化或终结逻辑。
完整示例
负载测试配置示例
rate: 20000
workers: 1000
worker-type: "dummy"
payload-template:
method: "POST"
path: "/foo/?id={{ rand_int 1 10000000 }}"
worker-template:
print: false
base: "https://{{ .region }}.my-api.com"
min: 10
max: 20
worker-variants:
- region: "europe-west1"
- region: "us-east1"
批量API任务配置示例
# 数据通常是本地CSV文件或GCS存储桶中的对象
data: |
user_name,action
dave,subscribe
john,subscribe
pete,unsubscribe
jimmy,unsubscribe
resume: true
log: "out.log"
rate: 100
workers: 20
worker-type: "dummy"
payload-template:
method: "POST"
path: "/{{ .user_name }}/{{ .action }}/{{ .type }}/"
worker-template:
print: true
base: "https://{{ .region }}.my-api.com"
min: 250
max: 500
payload-variants:
- type: "email"
- type: "phone"
worker-variants:
- region: "europe-west1"
- region: "us-east1"
log-data:
- "user_name"
- "action"
log-output:
- "status"
代码控制示例
ctx, cancel := context.WithCancel(context.Background())
b := blaster.New(ctx, cancel)
defer b.Exit()
b.SetWorker(func() blaster.Worker {
return &blaster.ExampleWorker{
SendFunc: func(ctx context.Context, self *blaster.ExampleWorker, in map[string]interface{}) (map[string]interface{}, error) {
return map[string]interface{}{"status": 200}, nil
},
}
})
b.Headers = []string{"header"}
b.SetData(strings.NewReader("foo\nbar"))
stats, err := b.Start(ctx)
if err != nil {
fmt.Println(err.Error())
return
}
fmt.Printf("Success == 2: %v\n", stats.All.Summary.Success == 2)
fmt.Printf("Fail == 0: %v", stats.All.Summary.Fail == 0)
// Output:
// Success == 2: true
// Fail == 0: true
待办事项
- [ ] 根据延迟自动调整速率?PID控制器?
- [ ] 仅使用文件的一部分:i部分中的j部分
更多关于golang高性能API负载测试与批量任务处理插件Blast的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang高性能API负载测试与批量任务处理插件Blast的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang高性能API负载测试与批量任务处理插件Blast使用指南
Blast是一个用Go语言编写的高性能HTTP负载测试工具和批量任务处理框架,特别适合API性能测试和大规模任务处理场景。
Blast核心特性
- 高性能:基于Go协程实现高并发
- 灵活配置:支持自定义请求参数、头信息和请求体
- 结果统计:提供详细的请求统计和性能指标
- 批量处理:支持任务队列和批量处理模式
- 扩展性强:可通过插件机制扩展功能
安装Blast
go get -u github.com/dave/blast
基础使用示例
1. 简单负载测试
package main
import (
"github.com/dave/blast"
"log"
"time"
)
func main() {
// 创建Blast实例
b := blast.New()
// 配置测试参数
b.
URL("https://api.example.com/users").
Method("GET").
Concurrency(100). // 并发数
Requests(1000). // 总请求数
Timeout(10 * time.Second). // 超时时间
Header("Authorization", "Bearer token123")
// 运行测试
result, err := b.Run()
if err != nil {
log.Fatal(err)
}
// 打印结果
log.Printf("Completed %d requests in %v", result.Requests, result.Duration)
log.Printf("Success rate: %.2f%%", result.SuccessRate()*100)
log.Printf("Requests per second: %.2f", result.RequestsPerSecond())
log.Printf("Average latency: %v", result.AverageLatency())
}
2. 带请求体的POST测试
func postTest() {
b := blast.New().
URL("https://api.example.com/users").
Method("POST").
Body([]byte(`{"name":"test","email":"test@example.com"}`)).
Header("Content-Type", "application/json").
Concurrency(50).
Requests(500)
result, err := b.Run()
if err != nil {
log.Fatal(err)
}
// 输出详细统计
log.Println(result.String())
}
高级功能
1. 批量任务处理
func batchProcessing() {
// 准备任务数据
userIDs := []string{"1", "2", "3", "4", "5"}
// 创建批量处理器
processor := blast.NewBatchProcessor().
Concurrency(10). // 并发处理数
Timeout(5 * time.Second)
// 添加处理函数
processor.Handle(func(id interface{}) (interface{}, error) {
userID := id.(string)
// 这里执行实际的任务处理逻辑
resp, err := http.Get(fmt.Sprintf("https://api.example.com/users/%s", userID))
if err != nil {
return nil, err
}
defer resp.Body.Close()
// 返回处理结果
return resp.Status, nil
})
// 提交任务并获取结果
results := processor.Process(userIDs)
// 处理结果
for _, result := range results {
if result.Error != nil {
log.Printf("Error processing task: %v", result.Error)
} else {
log.Printf("Task result: %v", result.Value)
}
}
}
2. 自定义请求生成器
func customRequestGenerator() {
b := blast.New().
Concurrency(20).
Requests(200).
RequestGenerator(func() *blast.Request {
// 动态生成请求
userID := rand.Intn(1000)
return &blast.Request{
Method: "GET",
URL: fmt.Sprintf("https://api.example.com/users/%d", userID),
Headers: map[string]string{
"Authorization": "Bearer token123",
},
}
})
result, err := b.Run()
if err != nil {
log.Fatal(err)
}
// 输出百分位延迟
log.Printf("50%% latency: %v", result.PercentileLatency(0.5))
log.Printf("95%% latency: %v", result.PercentileLatency(0.95))
log.Printf("99%% latency: %v", result.PercentileLatency(0.99))
}
性能优化建议
- 合理设置并发数:根据目标服务器性能和网络条件调整
- 使用连接池:Blast内部已经实现了HTTP连接复用
- 减少内存分配:重用请求对象和缓冲区
- 监控系统资源:避免测试客户端成为瓶颈
- 分布式测试:对于极高负载测试,考虑在多台机器上分布式运行
结果分析与可视化
Blast提供丰富的测试结果数据,可以集成到监控系统中:
func analyzeResults(result *blast.Result) {
// 输出详细统计
fmt.Println("=== 测试结果 ===")
fmt.Printf("总请求数: %d\n", result.Requests)
fmt.Printf("成功请求: %d\n", result.Success)
fmt.Printf("失败请求: %d\n", result.Failures)
fmt.Printf("总耗时: %v\n", result.Duration)
fmt.Printf("QPS: %.2f\n", result.RequestsPerSecond())
fmt.Printf("平均延迟: %v\n", result.AverageLatency())
fmt.Printf("最大延迟: %v\n", result.MaxLatency)
fmt.Printf("最小延迟: %v\n", result.MinLatency)
// 可以导出为JSON用于可视化
jsonData, _ := json.MarshalIndent(result, "", " ")
_ = os.WriteFile("test_result.json", jsonData, 0644)
}
Blast是一个强大而灵活的工具,通过合理配置可以满足从简单API测试到复杂批量任务处理的各种需求。其基于Go语言的特性使其在性能上具有明显优势,特别适合高并发场景下的性能测试和任务处理。