1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
| func HandleStatics(concurrency uint64, ch <-chan *response.ResponseResult) { var ( requestCostTimeList []uint64 processingTime uint64 = 0 requestCostTime uint64 = 0 maxTime uint64 = 0 minTime uint64 = 0 successNum uint64 = 0 failureNum uint64 = 0 chanIdLen uint64 = 0 stopChan = make(chan bool) mutex = sync.RWMutex{} chanIds = make(map[int]bool) )
startTime := uint64(time.Now().UnixNano()) respCodeMap := sync.Map{} ticker := time.NewTicker(time.Second) go func() { for { select { case <-ticker.C: endTime := uint64(time.Now().UnixNano()) mutex.Lock() go calculateData(concurrency, processingTime, endTime-startTime, maxTime, minTime, successNum, failureNum, chanIdLen, &respCodeMap) mutex.Unlock() case <-stopChan: return } } }() printHeader() for respRes := range ch { mutex.Lock() processingTime = processingTime + respRes.Cost if maxTime <= respRes.Cost { maxTime = respRes.Cost } if minTime == 0 { minTime = respRes.Cost } else if minTime > respRes.Cost { minTime = respRes.Cost } if respRes.IsSucceed { successNum = successNum + 1 } else { failureNum = failureNum + 1 }
if value, ok := respCodeMap.Load(respRes.StatusCode); ok { total, _ := value.(int) respCodeMap.Store(respRes.StatusCode, total+1) } else { respCodeMap.Store(respRes.StatusCode, 1) }
if _, ok := chanIds[int(respRes.ChanId)]; !ok { chanIds[int(respRes.ChanId)] = true chanIdLen = uint64(len(chanIds)) } requestCostTimeList = append(requestCostTimeList, respRes.Cost) mutex.Unlock() } stopChan <- true endTime := uint64(time.Now().UnixNano()) requestCostTime = endTime - startTime calculateData(concurrency, processingTime, requestCostTime, maxTime, minTime, successNum, failureNum, chanIdLen, &respCodeMap)
fmt.Printf("\n\n") fmt.Println("************************* 结果 stat ****************************") fmt.Println("处理协程数量:", concurrency) fmt.Println("请求总数(并发数*请求数 -c * -n):", successNum+failureNum, "总请求时间:", fmt.Sprintf("%.3f", float64(requestCostTime)/1e9), "秒", "successNum:", successNum, "failureNum:", failureNum) printTop(requestCostTimeList) fmt.Println("************************* 结果 end ****************************") fmt.Printf("\n\n") }
func calculateData(concurrent, processingTime, costTime, maxTime, minTime, successNum, failureNum, chanIdLen uint64, respCodeMap *sync.Map) { if processingTime == 0 || chanIdLen == 0 { return }
var qps, averageTime, maxTimeFloat, minTimeFloat, requestCostTimeFloat float64
qps = float64(successNum*1e9*concurrent) / float64(processingTime)
if successNum != 0 && concurrent != 0 { averageTime = float64(processingTime) / float64(successNum*1e6) } maxTimeFloat = float64(maxTime) / 1e6 minTimeFloat = float64(minTime) / 1e6 requestCostTimeFloat = float64(costTime) / 1e9
result := fmt.Sprintf("%4.0fs│%7d│%7d│%7d│%8.2f│%11.2f│%11.2f│%11.2f│%v", requestCostTimeFloat, chanIdLen, successNum, failureNum, qps, maxTimeFloat, minTimeFloat, averageTime, printMap(respCodeMap)) fmt.Println(result) }
func printHeader() { fmt.Printf("\n\n") fmt.Println("─────┬───────┬───────┬───────┬────────┬───────────┬───────────┬───────────┬────────") fmt.Println(" 耗时│ 并发数│ 成功数│ 失败数│ qps │最长耗时/ms│最短耗时/ms│平均耗时/ms│ 状态码") fmt.Println("─────┼───────┼───────┼───────┼────────┼───────────┼───────────┼───────────┼────────") return }
func printMap(respCodeMap *sync.Map) (mapStr string) { var mapArr []string
respCodeMap.Range(func(key, value interface{}) bool { mapArr = append(mapArr, fmt.Sprintf("%v:%v", key, value)) return true }) sort.Strings(mapArr) mapStr = strings.Join(mapArr, ";") return }
func printTop(requestCostTimeList []uint64) { if len(requestCostTimeList) == 0 { return } all := uint64Array{} all = requestCostTimeList sort.Sort(all) fmt.Println("tp90:", fmt.Sprintf("%.3fms", float64(all[int(float64(len(all))*0.90)]/1e6))) fmt.Println("tp95:", fmt.Sprintf("%.3fms", float64(all[int(float64(len(all))*0.95)]/1e6))) fmt.Println("tp99:", fmt.Sprintf("%.3fms", float64(all[int(float64(len(all))*0.99)]/1e6))) }
type uint64Array []uint64
func (array uint64Array) Len() int { return len(array) } func (array uint64Array) Swap(i, j int) { array[i], array[j] = array[j], array[i] } func (array uint64Array) Less(i, j int) bool { return array[i] < array[j] }
|