监控实现

This commit is contained in:
kercylan98 2023-05-24 11:04:34 +08:00
parent 3c0190eb27
commit 1913c4d3ca
2 changed files with 122 additions and 62 deletions

View File

@ -0,0 +1,102 @@
package main
import (
"github.com/kercylan98/minotaur/component/components"
"github.com/kercylan98/minotaur/game/builtin"
"github.com/kercylan98/minotaur/server"
"github.com/kercylan98/minotaur/utils/log"
"github.com/kercylan98/minotaur/utils/synchronization"
"github.com/kercylan98/minotaur/utils/timer"
"go.uber.org/zap"
"time"
)
type Player struct {
*builtin.Player[string]
}
type Command struct {
CMD int
Data string
}
// 访问http://www.websocket-test.com/
// - 使用多个页面连接到服务器后任一页面发送start即可开启帧同步
func main() {
players := synchronization.NewMap[string, *Player]()
srv := server.New(server.NetworkWebsocket,
server.WithWebsocketWriteMessageType(server.WebsocketMessageTypeText),
server.WithTicker(20, false),
server.WithMonitor(),
)
lockstep := components.NewLockstep[string, *Command]()
srv.RegStartFinishEvent(func(srv *server.Server) {
srv.Ticker().Loop("monitor", timer.Instantly, time.Second, timer.Forever, func() {
m := srv.GetMonitor()
log.Info("Monitor.Message",
zap.Any("MessageTotal", m.MessageTotal()),
zap.Any("MessageSecond", m.MessageSecond()),
zap.Any("MessageCost", m.MessageCost()),
zap.Any("MessageDoneAvg", m.MessageDoneAvg()),
zap.Any("MessageQPS", m.MessageQPS()),
zap.Any("MessageTopQPS", m.MessageTopQPS()),
)
log.Info("Monitor.Cross",
zap.Any("CrossMessageTotal", m.CrossMessageTotal()),
zap.Any("CrossMessageSecond", m.CrossMessageSecond()),
zap.Any("CrossMessageCost", m.CrossMessageCost()),
zap.Any("CrossMessageDoneAvg", m.CrossMessageDoneAvg()),
zap.Any("CrossMessageQPS", m.MessageQPS()),
zap.Any("CrossMessageTopQPS", m.CrossMessageTopQPS()),
)
log.Info("Monitor.Packet",
zap.Any("PacketMessageTotal", m.PacketMessageTotal()),
zap.Any("PacketMessageSecond", m.PacketMessageSecond()),
zap.Any("PacketMessageCost", m.PacketMessageCost()),
zap.Any("PacketMessageDoneAvg", m.PacketMessageDoneAvg()),
zap.Any("PacketMessageQPS", m.PacketMessageQPS()),
zap.Any("PacketMessageTopQPS", m.PacketMessageTopQPS()),
)
log.Info("Monitor.Ticker",
zap.Any("TickerMessageTotal", m.TickerMessageTotal()),
zap.Any("TickerMessageSecond", m.TickerMessageSecond()),
zap.Any("TickerMessageCost", m.TickerMessageCost()),
zap.Any("TickerMessageDoneAvg", m.TickerMessageDoneAvg()),
zap.Any("TickerMessageQPS", m.TickerMessageQPS()),
zap.Any("TickerMessageTopQPS", m.TickerMessageTopQPS()),
)
log.Info("Monitor.Error",
zap.Any("ErrorMessageTotal", m.ErrorMessageTotal()),
zap.Any("ErrorMessageSecond", m.ErrorMessageSecond()),
zap.Any("ErrorMessageCost", m.ErrorMessageCost()),
zap.Any("ErrorMessageDoneAvg", m.ErrorMessageDoneAvg()),
zap.Any("ErrorMessageQPS", m.ErrorMessageQPS()),
zap.Any("ErrorMessageTopQPS", m.ErrorMessageTopQPS()),
)
})
})
srv.RegConnectionOpenedEvent(func(srv *server.Server, conn *server.Conn) {
player := &Player{Player: builtin.NewPlayer[string](conn.GetID(), conn)}
players.Set(conn.GetID(), player)
lockstep.JoinClient(player)
})
srv.RegConnectionClosedEvent(func(srv *server.Server, conn *server.Conn) {
players.Delete(conn.GetID())
lockstep.LeaveClient(conn.GetID())
if players.Size() == 0 {
lockstep.Stop()
}
})
srv.RegConnectionReceiveWebsocketPacketEvent(func(srv *server.Server, conn *server.Conn, packet []byte, messageType int) {
switch string(packet) {
case "start":
lockstep.StartBroadcast()
default:
lockstep.AddCommand(&Command{CMD: 1, Data: string(packet)})
}
})
if err := srv.Run(":9999"); err != nil {
panic(err)
}
}

View File

@ -1,7 +1,6 @@
package server
import (
"encoding/json"
"github.com/kercylan98/minotaur/utils/timer"
"sync"
"time"
@ -84,102 +83,61 @@ type monitor struct {
tickerMessageTopQPS int64 // 定时器消息最高QPS
}
func (slf *monitor) String() string {
m := slf.Map()
bytes, _ := json.Marshal(m)
return string(bytes)
}
func (slf *monitor) Map() map[string]any {
var m = make(map[string]any)
m["messageTotal"] = slf.messageTotal
m["packetMessageTotal"] = slf.packetMessageTotal
m["errorMessageTotal"] = slf.errorMessageTotal
m["crossMessageTotal"] = slf.crossMessageTotal
m["tickerMessageTotal"] = slf.tickerMessageTotal
m["messageSecond"] = slf.messageSecond
m["packetMessageSecond"] = slf.packetMessageSecond
m["errorMessageSecond"] = slf.errorMessageSecond
m["crossMessageSecond"] = slf.crossMessageSecond
m["tickerMessageSecond"] = slf.tickerMessageSecond
m["messageCost"] = slf.messageCost
m["packetMessageCost"] = slf.packetMessageCost
m["errorMessageCost"] = slf.errorMessageCost
m["crossMessageCost"] = slf.crossMessageCost
m["tickerMessageCost"] = slf.tickerMessageCost
m["messageDoneAvg"] = slf.messageDoneAvg
m["packetMessageDoneAvg"] = slf.packetMessageDoneAvg
m["errorMessageDoneAvg"] = slf.errorMessageDoneAvg
m["crossMessageDoneAvg"] = slf.crossMessageDoneAvg
m["tickerMessageDoneAvg"] = slf.tickerMessageDoneAvg
m["messageQPS"] = slf.messageQPS
m["packetMessageQPS"] = slf.packetMessageQPS
m["errorMessageQPS"] = slf.errorMessageQPS
m["crossMessageQPS"] = slf.crossMessageQPS
m["tickerMessageQPS"] = slf.tickerMessageQPS
m["messageTopQPS"] = slf.messageTopQPS
m["packetMessageTopQPS"] = slf.packetMessageTopQPS
m["errorMessageTopQPS"] = slf.errorMessageTopQPS
m["crossMessageTopQPS"] = slf.crossMessageTopQPS
m["tickerMessageTopQPS"] = slf.tickerMessageTopQPS
return m
}
func (slf *monitor) tick() {
slf.rwMutex.Lock()
// 秒平均响应时间
if nanoseconds := slf.messageCost.Nanoseconds(); nanoseconds == 0 {
if slf.messageSecond == 0 {
slf.messageDoneAvg = 0
} else {
slf.messageDoneAvg = time.Duration(nanoseconds / slf.messageSecond)
slf.messageDoneAvg = time.Duration(slf.messageCost.Nanoseconds() / slf.messageSecond)
}
if nanoseconds := slf.packetMessageCost.Nanoseconds(); nanoseconds == 0 {
if slf.packetMessageSecond == 0 {
slf.packetMessageDoneAvg = 0
} else {
slf.packetMessageDoneAvg = time.Duration(nanoseconds / slf.packetMessageSecond)
slf.packetMessageDoneAvg = time.Duration(slf.packetMessageCost.Nanoseconds() / slf.packetMessageSecond)
}
if nanoseconds := slf.errorMessageCost.Nanoseconds(); nanoseconds == 0 {
if slf.errorMessageSecond == 0 {
slf.errorMessageDoneAvg = 0
} else {
slf.errorMessageDoneAvg = time.Duration(nanoseconds / slf.errorMessageSecond)
slf.errorMessageDoneAvg = time.Duration(slf.errorMessageCost.Nanoseconds() / slf.errorMessageSecond)
}
if nanoseconds := slf.crossMessageCost.Nanoseconds(); nanoseconds == 0 {
if slf.crossMessageSecond == 0 {
slf.crossMessageDoneAvg = 0
} else {
slf.crossMessageDoneAvg = time.Duration(nanoseconds / slf.crossMessageSecond)
slf.crossMessageDoneAvg = time.Duration(slf.crossMessageCost.Nanoseconds() / slf.crossMessageSecond)
}
if nanoseconds := slf.tickerMessageCost.Nanoseconds(); nanoseconds == 0 {
if slf.tickerMessageSecond == 0 {
slf.tickerMessageDoneAvg = 0
} else {
slf.tickerMessageDoneAvg = time.Duration(nanoseconds / slf.tickerMessageSecond)
slf.tickerMessageDoneAvg = time.Duration(slf.tickerMessageCost.Nanoseconds() / slf.tickerMessageSecond)
}
// 秒 QPS
if slf.messageSecond == 0 {
if nanoseconds := slf.messageDoneAvg.Nanoseconds(); nanoseconds == 0 {
slf.messageQPS = 0
} else {
slf.messageQPS = slf.messageSecond / slf.messageDoneAvg.Nanoseconds()
slf.messageQPS = slf.messageSecond / nanoseconds
}
if slf.packetMessageSecond == 0 {
if nanoseconds := slf.packetMessageDoneAvg.Nanoseconds(); nanoseconds == 0 {
slf.packetMessageQPS = 0
} else {
slf.packetMessageQPS = slf.packetMessageSecond / slf.packetMessageDoneAvg.Nanoseconds()
slf.packetMessageQPS = slf.packetMessageSecond / nanoseconds
}
if slf.errorMessageSecond == 0 {
if nanoseconds := slf.errorMessageDoneAvg.Nanoseconds(); nanoseconds == 0 {
slf.errorMessageQPS = 0
} else {
slf.errorMessageQPS = slf.errorMessageSecond / slf.errorMessageDoneAvg.Nanoseconds()
slf.errorMessageQPS = slf.errorMessageSecond / nanoseconds
}
if slf.crossMessageSecond == 0 {
if nanoseconds := slf.crossMessageDoneAvg.Nanoseconds(); nanoseconds == 0 {
slf.crossMessageQPS = 0
} else {
slf.crossMessageQPS = slf.crossMessageSecond / slf.crossMessageDoneAvg.Nanoseconds()
slf.crossMessageQPS = slf.crossMessageSecond / nanoseconds
}
if slf.tickerMessageSecond == 0 {
if nanoseconds := slf.tickerMessageDoneAvg.Nanoseconds(); nanoseconds == 0 {
slf.tickerMessageQPS = 0
} else {
slf.tickerMessageQPS = slf.tickerMessageSecond / slf.tickerMessageDoneAvg.Nanoseconds()
slf.tickerMessageQPS = slf.tickerMessageSecond / nanoseconds
}
// Top QPS