From 32c08c61067c1f2f7210e1a726ba647bcbcb3569 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Wed, 24 May 2023 11:29:20 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4=E7=9B=91=E6=8E=A7=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E4=B8=8D=E5=90=88=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../simple-server-lockstep-monitor/main.go | 104 ------ server/errors.go | 1 - server/monitor.go | 341 ------------------ server/options.go | 10 - server/server.go | 19 - 5 files changed, 475 deletions(-) delete mode 100644 examples/simple-server-lockstep-monitor/main.go delete mode 100644 server/monitor.go diff --git a/examples/simple-server-lockstep-monitor/main.go b/examples/simple-server-lockstep-monitor/main.go deleted file mode 100644 index 561c00f..0000000 --- a/examples/simple-server-lockstep-monitor/main.go +++ /dev/null @@ -1,104 +0,0 @@ -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/random" - "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/2, timer.Forever, func() { - m := srv.GetMonitor() - log.Info("Monitor.Message", - zap.Any("Total", m.MessageTotal()), - zap.Any("Second", m.MessageSecond()), - zap.Any("Cost", m.MessageCost()), - zap.Any("DoneAvg", m.MessageDoneAvg()), - zap.Any("QPS", m.MessageQPS()), - zap.Any("TopQPS", m.MessageTopQPS()), - ) - log.Info("Monitor.Cross", - zap.Any("Total", m.CrossMessageTotal()), - zap.Any("Second", m.CrossMessageSecond()), - zap.Any("Cost", m.CrossMessageCost()), - zap.Any("DoneAvg", m.CrossMessageDoneAvg()), - zap.Any("QPS", m.MessageQPS()), - zap.Any("TopQPS", m.CrossMessageTopQPS()), - ) - log.Info("Monitor.Packet", - zap.Any("Total", m.PacketMessageTotal()), - zap.Any("Second", m.PacketMessageSecond()), - zap.Any("Cost", m.PacketMessageCost()), - zap.Any("DoneAvg", m.PacketMessageDoneAvg()), - zap.Any("QPS", m.PacketMessageQPS()), - zap.Any("TopQPS", m.PacketMessageTopQPS()), - ) - log.Info("Monitor.Ticker", - zap.Any("Total", m.TickerMessageTotal()), - zap.Any("Second", m.TickerMessageSecond()), - zap.Any("Cost", m.TickerMessageCost()), - zap.Any("DoneAvg", m.TickerMessageDoneAvg()), - zap.Any("QPS", m.TickerMessageQPS()), - zap.Any("TopQPS", m.TickerMessageTopQPS()), - ) - log.Info("Monitor.Error", - zap.Any("Total", m.ErrorMessageTotal()), - zap.Any("Second", m.ErrorMessageSecond()), - zap.Any("Cost", m.ErrorMessageCost()), - zap.Any("DoneAvg", m.ErrorMessageDoneAvg()), - zap.Any("QPS", m.ErrorMessageQPS()), - zap.Any("TopQPS", 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: - time.Sleep(random.Duration(1, 3) * time.Second) - lockstep.AddCommand(&Command{CMD: 1, Data: string(packet)}) - } - }) - if err := srv.Run(":9999"); err != nil { - panic(err) - } -} diff --git a/server/errors.go b/server/errors.go index 4a83065..855f40e 100644 --- a/server/errors.go +++ b/server/errors.go @@ -19,7 +19,6 @@ var ( ErrPleaseUseWebsocketHandle = errors.New("in Websocket mode, please use the RegConnectionReceiveWebsocketPacketEvent function to register") ErrPleaseUseOrdinaryPacketHandle = errors.New("non Websocket mode, please use the RegConnectionReceivePacketEvent function to register") ErrNoSupportCross = errors.New("the server does not support GetID or PushCrossMessage, please use the WithCross option to create the server") - ErrNoSupportMonitor = errors.New("the server does not support GetMonitor, please use the WithMonitor option to create the server") ErrNoSupportTicker = errors.New("the server does not support Ticker, please use the WithTicker option to create the server") ErrUnregisteredCrossName = errors.New("unregistered cross name, please use the WithCross option to create the server") ) diff --git a/server/monitor.go b/server/monitor.go deleted file mode 100644 index 7595c63..0000000 --- a/server/monitor.go +++ /dev/null @@ -1,341 +0,0 @@ -package server - -import ( - "github.com/kercylan98/minotaur/utils/timer" - "sync" - "time" -) - -func newMonitor() *monitor { - m := &monitor{ - ticker: timer.GetTicker(10), - } - m.ticker.Loop("tick", timer.Instantly, time.Second, timer.Forever, m.tick) - return m -} - -type Monitor interface { - MessageTotal() int64 - PacketMessageTotal() int64 - ErrorMessageTotal() int64 - CrossMessageTotal() int64 - TickerMessageTotal() int64 - MessageSecond() int64 - PacketMessageSecond() int64 - ErrorMessageSecond() int64 - CrossMessageSecond() int64 - TickerMessageSecond() int64 - MessageCost() time.Duration - PacketMessageCost() time.Duration - ErrorMessageCost() time.Duration - CrossMessageCost() time.Duration - TickerMessageCost() time.Duration - MessageDoneAvg() time.Duration - PacketMessageDoneAvg() time.Duration - ErrorMessageDoneAvg() time.Duration - CrossMessageDoneAvg() time.Duration - TickerMessageDoneAvg() time.Duration - MessageQPS() int64 - PacketMessageQPS() int64 - ErrorMessageQPS() int64 - CrossMessageQPS() int64 - TickerMessageQPS() int64 - MessageTopQPS() int64 - PacketMessageTopQPS() int64 - ErrorMessageTopQPS() int64 - CrossMessageTopQPS() int64 - TickerMessageTopQPS() int64 -} - -type monitor struct { - rwMutex sync.RWMutex - ticker *timer.Ticker - - messageTotal int64 // 正在执行的消息总数 - packetMessageTotal int64 // 正在执行的玩家消息总数 - errorMessageTotal int64 // 正在执行的错误消息总数 - crossMessageTotal int64 // 正在执行的跨服消息总数 - tickerMessageTotal int64 // 正在执行的定时器消息总数 - messageSecond int64 // 一秒内执行的消息并发量 - packetMessageSecond int64 // 一秒内玩家消息并发量 - errorMessageSecond int64 // 一秒内错误消息并发量 - crossMessageSecond int64 // 一秒内跨服消息并发量 - tickerMessageSecond int64 // 一秒内定时器消息并发量 - messageCost time.Duration // 一秒内执行的消息总耗时 - packetMessageCost time.Duration // 一秒内玩家消息总耗时 - errorMessageCost time.Duration // 一秒内错误消息总耗时 - crossMessageCost time.Duration // 一秒内跨服消息总耗时 - tickerMessageCost time.Duration // 一秒内定时器消息总耗时 - messageDoneAvg time.Duration // 一秒内执行的消息平均响应时间 - packetMessageDoneAvg time.Duration // 一秒内玩家消息平均响应时间 - errorMessageDoneAvg time.Duration // 一秒内错误消息平均响应时间 - crossMessageDoneAvg time.Duration // 一秒内跨服消息平均响应时间 - tickerMessageDoneAvg time.Duration // 一秒内定时器消息平均响应时间 - messageQPS int64 // 一秒内执行的消息QPS - packetMessageQPS int64 // 一秒内玩家消息QPS - errorMessageQPS int64 // 一秒内错误消息QPS - crossMessageQPS int64 // 一秒内跨服消息QPS - tickerMessageQPS int64 // 一秒内定时器消息QPS - messageTopQPS int64 // 执行的消息最高QPS - packetMessageTopQPS int64 // 玩家消息最高QPS - errorMessageTopQPS int64 // 错误消息最高QPS - crossMessageTopQPS int64 // 跨服消息最高QPS - tickerMessageTopQPS int64 // 定时器消息最高QPS -} - -func (slf *monitor) tick() { - slf.rwMutex.Lock() - - // 秒平均响应时间 - if slf.messageSecond == 0 { - slf.messageDoneAvg = 0 - } else { - slf.messageDoneAvg = time.Duration(slf.messageCost.Nanoseconds() / slf.messageSecond) - } - if slf.packetMessageSecond == 0 { - slf.packetMessageDoneAvg = 0 - } else { - slf.packetMessageDoneAvg = time.Duration(slf.packetMessageCost.Nanoseconds() / slf.packetMessageSecond) - } - if slf.errorMessageSecond == 0 { - slf.errorMessageDoneAvg = 0 - } else { - slf.errorMessageDoneAvg = time.Duration(slf.errorMessageCost.Nanoseconds() / slf.errorMessageSecond) - } - if slf.crossMessageSecond == 0 { - slf.crossMessageDoneAvg = 0 - } else { - slf.crossMessageDoneAvg = time.Duration(slf.crossMessageCost.Nanoseconds() / slf.crossMessageSecond) - } - if slf.tickerMessageSecond == 0 { - slf.tickerMessageDoneAvg = 0 - } else { - slf.tickerMessageDoneAvg = time.Duration(slf.tickerMessageCost.Nanoseconds() / slf.tickerMessageSecond) - } - - // 秒 QPS - if nanoseconds := slf.messageDoneAvg.Nanoseconds(); nanoseconds == 0 { - slf.messageQPS = 0 - } else { - slf.messageQPS = slf.messageSecond / nanoseconds - } - if nanoseconds := slf.packetMessageDoneAvg.Nanoseconds(); nanoseconds == 0 { - slf.packetMessageQPS = 0 - } else { - slf.packetMessageQPS = slf.packetMessageSecond / nanoseconds - } - if nanoseconds := slf.errorMessageDoneAvg.Nanoseconds(); nanoseconds == 0 { - slf.errorMessageQPS = 0 - } else { - slf.errorMessageQPS = slf.errorMessageSecond / nanoseconds - } - if nanoseconds := slf.crossMessageDoneAvg.Nanoseconds(); nanoseconds == 0 { - slf.crossMessageQPS = 0 - } else { - slf.crossMessageQPS = slf.crossMessageSecond / nanoseconds - } - if nanoseconds := slf.tickerMessageDoneAvg.Nanoseconds(); nanoseconds == 0 { - slf.tickerMessageQPS = 0 - } else { - slf.tickerMessageQPS = slf.tickerMessageSecond / nanoseconds - } - - // Top QPS - if slf.messageQPS > slf.messageTopQPS { - slf.messageTopQPS = slf.messageQPS - } - if slf.packetMessageQPS > slf.packetMessageTopQPS { - slf.packetMessageTopQPS = slf.packetMessageQPS - } - if slf.errorMessageQPS > slf.errorMessageTopQPS { - slf.errorMessageTopQPS = slf.errorMessageQPS - } - if slf.crossMessageQPS > slf.crossMessageTopQPS { - slf.crossMessageTopQPS = slf.crossMessageQPS - } - if slf.tickerMessageQPS > slf.tickerMessageTopQPS { - slf.tickerMessageTopQPS = slf.tickerMessageQPS - } - - slf.messageSecond = 0 - slf.packetMessageSecond = 0 - slf.errorMessageSecond = 0 - slf.crossMessageSecond = 0 - slf.tickerMessageSecond = 0 - slf.messageCost = 0 - slf.packetMessageCost = 0 - slf.errorMessageCost = 0 - slf.crossMessageCost = 0 - slf.tickerMessageCost = 0 - slf.rwMutex.Unlock() -} - -func (slf *monitor) messageRun(msg *Message) { - slf.rwMutex.Lock() - defer slf.rwMutex.Unlock() - switch msg.t { - case MessageTypePacket: - slf.packetMessageTotal++ - slf.packetMessageSecond++ - case MessageTypeError: - slf.errorMessageTotal++ - slf.errorMessageSecond++ - case MessageTypeCross: - slf.crossMessageTotal++ - slf.crossMessageSecond++ - case MessageTypeTicker: - slf.tickerMessageTotal++ - slf.tickerMessageSecond++ - default: - return - } - slf.messageTotal++ - slf.messageSecond++ -} - -func (slf *monitor) messageDone(msg *Message, cost time.Duration) { - slf.rwMutex.Lock() - defer slf.rwMutex.Unlock() - switch msg.t { - case MessageTypePacket: - slf.packetMessageTotal-- - slf.packetMessageCost += cost - case MessageTypeError: - slf.errorMessageTotal-- - slf.errorMessageCost += cost - case MessageTypeCross: - slf.crossMessageTotal-- - slf.crossMessageCost += cost - case MessageTypeTicker: - slf.tickerMessageTotal-- - slf.tickerMessageCost += cost - default: - return - } - slf.messageTotal-- - slf.messageCost += cost -} - -func (slf *monitor) close() { - slf.ticker.Release() -} - -func (slf *monitor) MessageTotal() int64 { - return slf.messageTotal -} - -func (slf *monitor) PacketMessageTotal() int64 { - return slf.packetMessageTotal -} - -func (slf *monitor) ErrorMessageTotal() int64 { - return slf.errorMessageTotal -} - -func (slf *monitor) CrossMessageTotal() int64 { - return slf.crossMessageTotal -} - -func (slf *monitor) TickerMessageTotal() int64 { - return slf.tickerMessageTotal -} - -func (slf *monitor) MessageSecond() int64 { - return slf.messageSecond -} - -func (slf *monitor) PacketMessageSecond() int64 { - return slf.packetMessageSecond -} - -func (slf *monitor) ErrorMessageSecond() int64 { - return slf.errorMessageSecond -} - -func (slf *monitor) CrossMessageSecond() int64 { - return slf.crossMessageSecond -} - -func (slf *monitor) TickerMessageSecond() int64 { - return slf.tickerMessageSecond -} - -func (slf *monitor) MessageCost() time.Duration { - return slf.messageCost -} - -func (slf *monitor) PacketMessageCost() time.Duration { - return slf.packetMessageCost -} - -func (slf *monitor) ErrorMessageCost() time.Duration { - return slf.errorMessageCost -} - -func (slf *monitor) CrossMessageCost() time.Duration { - return slf.crossMessageCost -} - -func (slf *monitor) TickerMessageCost() time.Duration { - return slf.tickerMessageCost -} - -func (slf *monitor) MessageDoneAvg() time.Duration { - return slf.messageDoneAvg -} - -func (slf *monitor) PacketMessageDoneAvg() time.Duration { - return slf.packetMessageDoneAvg -} - -func (slf *monitor) ErrorMessageDoneAvg() time.Duration { - return slf.errorMessageDoneAvg -} - -func (slf *monitor) CrossMessageDoneAvg() time.Duration { - return slf.crossMessageDoneAvg -} - -func (slf *monitor) TickerMessageDoneAvg() time.Duration { - return slf.tickerMessageDoneAvg -} - -func (slf *monitor) MessageQPS() int64 { - return slf.messageQPS -} - -func (slf *monitor) PacketMessageQPS() int64 { - return slf.packetMessageQPS -} - -func (slf *monitor) ErrorMessageQPS() int64 { - return slf.errorMessageQPS -} - -func (slf *monitor) CrossMessageQPS() int64 { - return slf.crossMessageQPS -} - -func (slf *monitor) TickerMessageQPS() int64 { - return slf.tickerMessageQPS -} - -func (slf *monitor) MessageTopQPS() int64 { - return slf.messageTopQPS -} - -func (slf *monitor) PacketMessageTopQPS() int64 { - return slf.packetMessageTopQPS -} - -func (slf *monitor) ErrorMessageTopQPS() int64 { - return slf.errorMessageTopQPS -} - -func (slf *monitor) CrossMessageTopQPS() int64 { - return slf.crossMessageTopQPS -} - -func (slf *monitor) TickerMessageTopQPS() int64 { - return slf.tickerMessageTopQPS -} diff --git a/server/options.go b/server/options.go index 1dd7d26..440fa3f 100644 --- a/server/options.go +++ b/server/options.go @@ -23,16 +23,6 @@ const ( type Option func(srv *Server) -// WithMonitor 通过监控的方式创建服务器 -// - 需要注意在消息被转为异步处理时会导致部分指标不可信 -func WithMonitor() Option { - return func(srv *Server) { - if srv.monitor == nil { - srv.monitor = newMonitor() - } - } -} - // WithTicker 通过定时器创建服务器,为服务器添加定时器功能 // - autonomy:定时器是否独立运行(独立运行的情况下不会作为服务器消息运行,会导致并发问题) // - 多核与分流情况下需要考虑是否有必要 autonomy diff --git a/server/server.go b/server/server.go index cf5381c..fe1ef99 100644 --- a/server/server.go +++ b/server/server.go @@ -52,7 +52,6 @@ func New(network Network, options ...Option) *Server { // Server 网络服务器 type Server struct { *event // 事件 - monitor *monitor // 监控 cross map[string]Cross // 跨服 id int64 // 服务器id network Network // 网络类型 @@ -333,14 +332,6 @@ func (slf *Server) Ticker() *timer.Ticker { return slf.ticker } -// GetMonitor 获取服务器监控信息 -func (slf *Server) GetMonitor() Monitor { - if slf.monitor == nil { - panic(ErrNoSupportMonitor) - } - return slf.monitor -} - // Shutdown 停止运行服务器 func (slf *Server) Shutdown(err error, stack ...string) { slf.isShutdown.Store(true) @@ -374,10 +365,6 @@ func (slf *Server) Shutdown(err error, stack ...string) { log.Error("Server", zap.Error(shutdownErr)) } } - if slf.monitor != nil { - slf.monitor.close() - slf.monitor = nil - } if err != nil { var s string @@ -452,15 +439,9 @@ func (slf *Server) dispatchMessage(msg *Message) { } if !slf.isShutdown.Load() { - if slf.monitor != nil { - slf.monitor.messageDone(msg, cost) - } slf.messagePool.Release(msg) } }() - if slf.monitor != nil { - slf.monitor.messageRun(msg) - } switch msg.t { case MessageTypePacket: if slf.network == NetworkWebsocket {