160 lines
4.5 KiB
Go
160 lines
4.5 KiB
Go
package battletest
|
|
|
|
import (
|
|
"fmt"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/lego/core"
|
|
"go_dreamfactory/lego/core/cbase"
|
|
"go_dreamfactory/lego/sys/log"
|
|
"go_dreamfactory/lego/sys/mgo"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/utils"
|
|
"os"
|
|
"sync"
|
|
"sync/atomic"
|
|
"time"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
// 压测组件
|
|
type pressuretestComp struct {
|
|
cbase.ModuleCompBase
|
|
module *BattleTest
|
|
report *pb.BattleReport
|
|
lock sync.RWMutex
|
|
workers []*worker
|
|
state int32 //状态 1 运行 2结束
|
|
start time.Time //开始时间
|
|
end time.Time //结束时间
|
|
msgsize int64
|
|
cmdnum int64
|
|
round int64
|
|
battleinfosize int64
|
|
}
|
|
|
|
// 组件初始化接口
|
|
func (this *pressuretestComp) 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.(*BattleTest)
|
|
return
|
|
}
|
|
|
|
func (this *pressuretestComp) Start() (err error) {
|
|
err = this.ModuleCompBase.Start()
|
|
var (
|
|
db mgo.ISys
|
|
)
|
|
if db, err = mgo.NewSys(
|
|
mgo.SetMongodbUrl(this.module.options.MongodbUrl),
|
|
mgo.SetMongodbDatabase(this.module.options.MongodbDatabase),
|
|
); err != nil {
|
|
return
|
|
}
|
|
result := &pb.DBBattlePlayRecord{}
|
|
if err = db.FindOne(core.SqlTable(comm.TableBattlerecord), bson.M{"_id": this.module.options.BattleReportId}).Decode(result); err != nil {
|
|
return
|
|
}
|
|
this.report = &pb.BattleReport{}
|
|
this.msgsize = int64(len(result.Record))
|
|
if err = proto.Unmarshal(result.Record, this.report); err != nil {
|
|
return
|
|
}
|
|
this.cmdnum = int64(len(this.report.Outcmd))
|
|
this.round = int64(this.report.Round)
|
|
datas, _ := proto.Marshal(this.report.Info)
|
|
this.battleinfosize = int64(len(datas))
|
|
for _, v := range this.report.Outcmd {
|
|
datas, _ := proto.Marshal(v)
|
|
log.Debugf("指令:%s大小 %s:", v.Cmdtype, utils.FormatByesSize(int64(len(datas))))
|
|
}
|
|
this.cmdnum = int64(len(this.report.Outcmd))
|
|
this.workers = make([]*worker, this.module.options.Workers)
|
|
this.start = time.Now()
|
|
this.state = 1
|
|
go this.worker()
|
|
go this.run()
|
|
return
|
|
}
|
|
|
|
func (this *pressuretestComp) worker() {
|
|
var wg sync.WaitGroup
|
|
for i := int32(0); i < this.module.options.Workers; i++ {
|
|
this.workers[i] = &worker{
|
|
module: this.module,
|
|
report: this.report,
|
|
statistics: make([]int64, 0, this.module.options.TestNum),
|
|
testnum: this.module.options.TestNum,
|
|
}
|
|
wg.Add(1)
|
|
go this.workers[i].Worker(&wg)
|
|
}
|
|
wg.Wait()
|
|
log.Debug("[测试结束]")
|
|
this.end = time.Now()
|
|
atomic.StoreInt32(&this.state, 2)
|
|
}
|
|
|
|
func (this *pressuretestComp) run() {
|
|
timer := time.NewTicker(time.Second * 10)
|
|
locp:
|
|
for {
|
|
select {
|
|
case <-timer.C:
|
|
this.OutReport()
|
|
this.end = time.Now()
|
|
if atomic.LoadInt32(&this.state) == 2 {
|
|
break locp
|
|
}
|
|
}
|
|
}
|
|
timer.Stop()
|
|
log.Debug("[机器人 WTask]")
|
|
}
|
|
|
|
//输出报表
|
|
func (this *pressuretestComp) OutReport() {
|
|
var (
|
|
workers [][]int64 = make([][]int64, this.module.options.Workers)
|
|
num1, num2, num3, num4, num5 int
|
|
)
|
|
|
|
for i, v := range this.workers {
|
|
dst := make([]int64, len(v.statistics))
|
|
copy(dst, v.statistics)
|
|
workers[i] = dst
|
|
}
|
|
|
|
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.Workers))
|
|
file.WriteString(fmt.Sprintf("消息总请求数: %d\n", this.module.options.Workers*this.module.options.TestNum))
|
|
file.WriteString(fmt.Sprintf("回合数: %d\n", this.round))
|
|
file.WriteString(fmt.Sprintf("战报InfoSize: %s\n", utils.FormatByesSize(this.battleinfosize)))
|
|
file.WriteString(fmt.Sprintf("指令数: %d\n", (this.cmdnum)))
|
|
file.WriteString(fmt.Sprintf("消息总请求大小: %s\n", utils.FormatByesSize(this.msgsize)))
|
|
file.WriteString(fmt.Sprintf("压测执行时长: %.2f秒\n", this.end.Sub(this.start).Seconds()))
|
|
file.WriteString("0-5ms------------------5-10ms -------------------10-20ms -------------------------20-50ms-------------------->50ms\n")
|
|
for _, data := range workers {
|
|
for _, num := range data {
|
|
if num <= 5 {
|
|
num1++
|
|
} else if num <= 10 {
|
|
num2++
|
|
} else if num <= 20 {
|
|
num3++
|
|
} else if num <= 50 {
|
|
num4++
|
|
} else {
|
|
num5++
|
|
}
|
|
}
|
|
}
|
|
file.WriteString(fmt.Sprintf("%-5d次 ------------------%-5d次 -------------------%-5d次 -------------------------%-5d次-------------------->%-5d次\n", num1, num2, num3, num4, num5))
|
|
}
|