监控实现
This commit is contained in:
parent
3c0190eb27
commit
1913c4d3ca
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue