// benchmark.go 压测的主体逻辑
package main
import (
"fmt"
"sort"
"time"
)
type websitechecker func(url string) (time.Duration, error)
type result struct {
time.Duration
error
}
// Checker 对目标url进行压力测试
func Checker(wc websitechecker, url string, concurrency int, times int) {
resultChannel := make(chan result)
// 收集结果
durations := []time.Duration{}
var sum time.Duration
// 并发执行压力测试
for i := 0; i < times; i++ {
for j := 0; j < concurrency; j++ {
go func(u string) {
duration, err := wc(u)
resultChannel <- result{duration, err}
}(url)
}
for j := 0; j < concurrency; j++ {
ret := <-resultChannel
if ret.error != nil {
fmt.Printf("error %v", ret.error)
continue
}
durations = append(durations, ret.Duration)
sum += ret.Duration
}
}
// 排序和统计结果
sort.Slice(durations, func(i, j int) bool {
return durations[i] < durations[j]
})
errorCount := concurrency*times - len(durations)
p95 := len(durations) * 95 / 100
// 输出结果
fmt.Printf("successed %d, error %d, avg time %v ms, p95 = %v",
len(durations), errorCount,
int(sum.Microseconds())/len(durations)/1000,
durations[p95])
}
评论