Open wtysos11 opened 3 years ago
Hi 請問能否更詳細解答"读取文件设计动态访问"章節中的"计数器向上移动的时候就可以实现遍历",參考您的NewCustomTargeter範例還是沒讀明白T_T 疑問點是targeter如何撰寫才能有計數的效果,謝謝。
Hi 請問能否更詳細解答"读取文件设计动态访问"章節中的"计数器向上移动的时候就可以实现遍历",參考您的NewCustomTargeter範例還是沒讀明白T_T 疑問點是targeter如何撰寫才能有計數的效果,謝謝。
抱歉,之前做的时候写的demo和这个不一致,这句话所对应的目标是如何遍历给定的txt文件夹。 我做了一个新的demo
id.txt
TRA_1_index
TRA_2_index
TRA_3_index
TRA_4_index
TRA_5_index
压测端
package main
import (
"bufio"
"fmt"
"io"
"os"
"strings"
"time"
vegeta "github.com/tsenart/vegeta/v12/lib"
)
func main() {
rate := vegeta.Rate{Freq: 100, Per: time.Second}
duration := 4 * time.Second
targeter := NewCustomTargeter(vegeta.Target{
Method: "GET",
URL: "http://localhost:8080/test",
})
//测试的实现需要基于Attacker
attacker := vegeta.NewAttacker()
var metrics vegeta.Metrics
for res := range attacker.Attack(targeter, rate, duration, "random") {
metrics.Add(res)
}
metrics.Close()
fmt.Printf("99th percentile: %s\n", metrics.Latencies.P99)
}
func NewCustomTargeter(target vegeta.Target) vegeta.Targeter {
//读取id文件
idData, err := readRealData()
if err != nil {
panic(err)
}
//cachedArray := make([]bool, len(idData))
x := 0
return func(tgt *vegeta.Target) error {
//其中,tgt是作为指针传入的,是需要被修改的。后续HTTP请求的赋值都是来自tgt,所以看做是另外一个返回值会更好一些
*tgt = target
//tgt.URL += "/custom" + strconv.Itoa(rand.Intn(100))
tgt.URL += "/" + idData[x]
x++
if x >= len(idData) {
x = 0
}
//tgt.Header = http.Header{}
return nil
}
}
func readRealData() ([]string, error) {
//读取id.txt文件
filePath := "id.txt"
file, err := os.OpenFile(filePath, os.O_RDONLY, 0666)
if err != nil {
return nil, err
}
defer file.Close()
//数据格式为音频id,字符串`TRA_{albumid}_index`,albumid为6-10位数字,index为5位数字以内
//将其作为字符串读取并写入到slices中
idData := make([]string, 0, 1400000)
buf := bufio.NewReader(file)
for {
line, err := buf.ReadString('\n')
line = strings.TrimSpace(line)
idData = append(idData, line)
if err != nil {
if err == io.EOF {
break
} else {
return nil, err
}
}
}
return idData, nil
}
服务端部分的结果是
2022-06-07 16:55:49|14.132µs|200|GET|/test/TRA_1_index|::1|name=TRA_1_index|0 B|0 B||
2022-06-07 16:55:49|20.895µs|200|GET|/test/TRA_2_index|::1|name=TRA_2_index|0 B|0 B||
2022-06-07 16:55:49|20.918µs|200|GET|/test/TRA_3_index|::1|name=TRA_3_index|0 B|0 B||
2022-06-07 16:55:49|21.048µs|200|GET|/test/TRA_4_index|::1|name=TRA_4_index|0 B|0 B||
2022-06-07 16:55:49|12.286µs|200|GET|/test/TRA_5_index|::1|name=TRA_5_index|0 B|0 B||
2022-06-07 16:55:49|28.04µs|200|GET|/test/TRA_1_index|::1|name=TRA_1_index|0 B|0 B||
2022-06-07 16:55:49|49.178µs|200|GET|/test/TRA_2_index|::1|name=TRA_2_index|0 B|0 B||
2022-06-07 16:55:49|29.287µs|200|GET|/test/TRA_3_index|::1|name=TRA_3_index|0 B|0 B||
2022-06-07 16:55:49|45.1µs|200|GET|/test/TRA_4_index|::1|name=TRA_4_index|0 B|0 B||
2022-06-07 16:55:49|17.428µs|200|GET具体的|/test/TRA_5_index|::1|name=TRA_5_index|0 B|0 B||
这样就可以实现对id.txt中每一行数据的遍历,targeter范例在压测端的NewCustomTargeter
,其中的x可以视为一个闭包实现的静态变量
Vegeta压测工具学习与使用
参考资料:
安装
在确定GOBIN在PATH内时,直接使用
go get -u github.com/tsenart/vegeta
即可完成安装。简易使用
在iris服务器中开启一个简单的router
声明一个简单的txt(必须带上HTTP)
执行命令
vegeta attack -targets ./test.txt -duration=30s -rate=10000 > result.bin
,即可开启服务,进行测试。(PS:不知道为什么-rate=0
不支持,会报错误要求一个大于0的数)执行
vegeta report result.bin
即可拿到执行报告此外还支持golang的库内部链接,例如:
从golang程序中启动Vegeta
由于需要输入不同的元素或者控制元素的数量,一个想法是直接生成一个百万行的文件并插入,另外一个想法是直接在程序内启动。出于对更灵活的性能的追求,我还是想尝试一下后者。
使用DEBUG单步调试,发现
attack.Attack
根据issue中的回复可以看到,只要返回一个能够产生Targeter的函数即可。其中Targeter也是一个函数(类型为
type Targeter func(*Target) error
,而Target在我的理解中是即将发送的请求,原文为HTTP request blueprint
)而例子中的
atacker.Attack
的返回值是一个channel,相当于是vegeta attack
命令。其中attacker
对象由NewAttacker
创建,可以指定一些参数(比如最大并行数量等)Attack分析
attcker.attack
读取文件设计动态访问
因此,动态访问的实现原理就很明确了:
attack.go
的第365行),因此计数器向上移动的时候就可以实现遍历。下面做了一个小的demo来展示这个思想,服务端会接受一个
/test/nameX
作为接受变量,发送端会发送随机的/test/XXX
过去。服务端
压测端
之后,通过发送请求
curl http://localhost:8080/get/custom54
就可以查看触发的数量。