// 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])}
评论