166 lines
5.2 KiB
Go
166 lines
5.2 KiB
Go
package robot
|
|
|
|
import (
|
|
"fmt"
|
|
"go_dreamfactory/lego/core"
|
|
"go_dreamfactory/lego/core/cbase"
|
|
"go_dreamfactory/lego/sys/log"
|
|
"go_dreamfactory/utils"
|
|
"os"
|
|
"sort"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
/*
|
|
统计组件
|
|
*/
|
|
type statisticalComp struct {
|
|
cbase.ModuleCompBase
|
|
module *RobotModule
|
|
succclientNum int32 //链接成功客户端数
|
|
failclientNum int32 //链接失败客户端数
|
|
curonlineNum int32 //当前在线人数
|
|
maxonlineNum int32 //最大在线人数
|
|
robotdata map[string][]*RobotStatistics //机器人统计数据
|
|
receiveMsg map[string]int32 //接收消息数统计
|
|
receiveMsgSize map[string]int64 //接收消息数统计
|
|
lock sync.RWMutex
|
|
start time.Time //开始时间
|
|
end time.Time //结束时间
|
|
}
|
|
|
|
//组件初始化接口
|
|
func (this *statisticalComp) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
|
this.ModuleCompBase.Init(service, module, comp, options)
|
|
this.module = module.(*RobotModule)
|
|
this.robotdata = make(map[string][]*RobotStatistics)
|
|
this.receiveMsg = make(map[string]int32)
|
|
this.receiveMsgSize = make(map[string]int64)
|
|
return
|
|
}
|
|
|
|
func (this *statisticalComp) Start() (err error) {
|
|
err = this.ModuleCompBase.Start()
|
|
this.start = time.Now()
|
|
go this.run()
|
|
return
|
|
}
|
|
|
|
//添加成功客户端数
|
|
func (this *statisticalComp) AddSuccClient(robot *Robot) {
|
|
this.lock.Lock()
|
|
this.curonlineNum++
|
|
if this.curonlineNum > this.maxonlineNum {
|
|
this.maxonlineNum = this.curonlineNum
|
|
}
|
|
this.lock.Unlock()
|
|
}
|
|
|
|
//添加失败客户端数
|
|
func (this *statisticalComp) AddFailClient(robot *Robot, err error) {
|
|
this.failclientNum++
|
|
}
|
|
|
|
//机器人测试结束
|
|
func (this *statisticalComp) RobotFinishedTest(robot *Robot) {
|
|
this.lock.Lock()
|
|
this.robotdata[robot.Account()] = robot.statistics
|
|
for k, v := range robot.receiveNum {
|
|
this.receiveMsg[k] += v
|
|
}
|
|
for k, v := range robot.receiveSize {
|
|
this.receiveMsgSize[k] += v
|
|
}
|
|
this.curonlineNum--
|
|
this.succclientNum++
|
|
this.end = time.Now()
|
|
this.lock.Unlock()
|
|
}
|
|
|
|
//输出报表
|
|
func (this *statisticalComp) OutReport() {
|
|
var (
|
|
messages map[string][]int64 = make(map[string][]int64)
|
|
receive map[string]int32 = make(map[string]int32)
|
|
receiveSize map[string]int64 = make(map[string]int64)
|
|
totalmessage int32
|
|
totalreceive int32
|
|
totalreceiveSize int64
|
|
ok bool
|
|
)
|
|
this.lock.RLock()
|
|
for _, datas := range this.robotdata {
|
|
for _, v := range datas {
|
|
totalmessage++
|
|
if _, ok = messages[v.message]; !ok {
|
|
messages[v.message] = make([]int64, 0)
|
|
}
|
|
messages[v.message] = append(messages[v.message], v.time)
|
|
}
|
|
}
|
|
for k, v := range this.receiveMsg {
|
|
receive[k] = v
|
|
totalreceive += v
|
|
}
|
|
for k, v := range this.receiveMsgSize {
|
|
receiveSize[k] = v
|
|
totalreceiveSize += v
|
|
}
|
|
this.lock.RUnlock()
|
|
file, err := os.OpenFile(this.module.options.OutFilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
defer file.Close()
|
|
file.WriteString(fmt.Sprintf("机器人总数: %d\n", this.module.options.RobotTotalNum))
|
|
file.WriteString(fmt.Sprintf("成功数量: %d\n", this.succclientNum))
|
|
file.WriteString(fmt.Sprintf("失败数量: %d\n", this.failclientNum))
|
|
file.WriteString(fmt.Sprintf("最大同时在线人数: %d\n", this.maxonlineNum))
|
|
file.WriteString(fmt.Sprintf("压测执行时长: %.2f秒\n", this.end.Sub(this.start).Seconds()))
|
|
file.WriteString(fmt.Sprintf("消息总请求数: %d\n", totalmessage))
|
|
file.WriteString(fmt.Sprintf("消息总接收数: %d 接收消息总大小:%s\n", totalreceive, utils.FormatByesSize(totalreceiveSize)))
|
|
file.WriteString(fmt.Sprintf("QPS: %.2f\n", float64(totalmessage)/this.end.Sub(this.start).Seconds()))
|
|
file.WriteString("---消息压测详情----------------------------------------------------------------------------------------------------\n")
|
|
for message, data := range messages {
|
|
sort.Slice(data, func(i, j int) bool {
|
|
return data[i] < data[j]
|
|
})
|
|
max := data[len(data)-1]
|
|
min := data[0]
|
|
sum := int64(0)
|
|
for _, num := range data {
|
|
sum += num
|
|
}
|
|
avg := float64(sum) / float64(len(data))
|
|
var median float64
|
|
if len(data)%2 == 0 {
|
|
median = float64(data[len(data)/2-1]+data[len(data)/2]) / 2.0
|
|
} else {
|
|
median = float64(data[len(data)/2])
|
|
}
|
|
file.WriteString(fmt.Sprintf("消息名:%-20s 请求次数:%-5d 耗时最小:%-5dms 耗时最大:%-5dms 平均耗时:%-5.2fms 中位耗时:%-5.2fms \n", message, len(data), min, max, avg, median))
|
|
}
|
|
file.WriteString("---消息压测接收回包消息统计----------------------------------------------------------------------------------------------------\n")
|
|
for k, v := range receive {
|
|
file.WriteString(fmt.Sprintf("消息名:%-20s 请求次数:%-5d 请求总大小:%s\n", k, v, utils.FormatByesSize(receiveSize[k])))
|
|
}
|
|
}
|
|
|
|
func (this *statisticalComp) run() {
|
|
timer := time.NewTicker(time.Second * 10)
|
|
locp:
|
|
for {
|
|
select {
|
|
case <-timer.C:
|
|
this.OutReport()
|
|
if this.failclientNum+this.succclientNum >= this.module.options.RobotTotalNum {
|
|
break locp
|
|
}
|
|
}
|
|
}
|
|
timer.Stop()
|
|
log.Debug("[机器人 WTask]")
|
|
}
|