diff --git a/common/cool/rpc.go b/common/cool/rpc.go index 7a8bf2e85..7401bdf59 100644 --- a/common/cool/rpc.go +++ b/common/cool/rpc.go @@ -7,9 +7,19 @@ func AddClient(id uint32, client *ClientHandler) { } // 取值示例 -func GetClient(id uint32) (*ClientHandler, bool) { +func GetClient(id, port uint32) (*ClientHandler, bool) { // 普通map:client, ok := Clientmap[id] - val, ok := Clientmap.Load(id) // sync.Map取值 + val, ok := Clientmap.Load(100000*id + port) // sync.Map取值 + if !ok { + return nil, false + } + // 类型断言(确保value是*ClientHandler) + client, ok := val.(*ClientHandler) + return client, ok +} +func GetClientOnly(uid uint32) (*ClientHandler, bool) { + // 普通map:client, ok := Clientmap[id] + val, ok := Clientmap.Load(uid) // sync.Map取值 if !ok { return nil, false } diff --git a/common/rpc/rpc.go b/common/rpc/rpc.go index 5560e3b38..428820c19 100644 --- a/common/rpc/rpc.go +++ b/common/rpc/rpc.go @@ -25,7 +25,7 @@ func (*ServerHandler) Kick(_ context.Context, userid uint32) error { return nil } - cl, ok := cool.GetClient(useid1) + cl, ok := cool.GetClientOnly(useid1) if !ok { return nil } @@ -44,7 +44,7 @@ func (*ServerHandler) RegisterLogic(ctx context.Context, id, port uint32) error } t := config.NewServerService().GetServerID((id)) - aa, ok := cool.GetClient(t.OnlineID*100000 + t.Port) + aa, ok := cool.GetClient(t.OnlineID, t.Port) if ok && aa != nil { //如果已经存在且这个端口已经被存过 aa.QuitSelf(0) } @@ -72,7 +72,7 @@ func StartClient(id, port uint32, callback any) *struct { RegisterLogic func(uint32, uint32) error } { - // cool.Config.File.Domain = "127.0.0.1" + //cool.Config.File.Domain = "127.0.0.1" var rpcaddr = "ws://" + cool.Config.File.Domain + gconv.String(cool.Config.Address) + "/rpc" closer1, err := jsonrpc.NewMergeClient(context.Background(), diff --git a/help/诊断较慢.sql b/help/诊断较慢.sql new file mode 100644 index 000000000..ea2d2ac75 --- /dev/null +++ b/help/诊断较慢.sql @@ -0,0 +1,18 @@ +-- 查看当前活跃的 SQL(排查慢查询) +SELECT pid, now() - query_start AS duration, query +FROM pg_stat_activity +WHERE state = 'active' AND now() - query_start > '5 seconds'::interval; + +-- 查看表的访问统计(找出热点表) +SELECT relname, seq_scan, idx_scan, n_live_tup +FROM pg_stat_user_tables +ORDER BY seq_scan DESC LIMIT 10; + +-- 查看索引使用情况(找出未使用的索引) +SELECT relname AS table_name, indexrelname AS index_name, idx_scan +FROM pg_stat_user_indexes +WHERE idx_scan = 0; + +-- 更新统计信息(当执行计划不准时) +ANALYZE users; -- 单表更新 +ANALYZE; -- 全库更新 \ No newline at end of file diff --git a/logic/controller/Controller.go b/logic/controller/Controller.go index f17bbb16c..bc99f7913 100644 --- a/logic/controller/Controller.go +++ b/logic/controller/Controller.go @@ -23,7 +23,7 @@ var Maincontroller = &Controller{} //注入service // Controller 分发cmd逻辑实现 type Controller struct { - Port uint32 + UID uint32 RPCClient *struct { Kick func(uint32) error diff --git a/logic/controller/item_use.go b/logic/controller/item_use.go index cf6821a29..6b62c8fc9 100644 --- a/logic/controller/item_use.go +++ b/logic/controller/item_use.go @@ -23,18 +23,16 @@ const ( // 返回: 道具列表和错误码 func (h Controller) GetUserItemList(data *item.ItemListInboundInfo, c *player.Player) (result *item.ItemListOutboundInfo, err errorcode.ErrorCode) { result = &item.ItemListOutboundInfo{} - result.ItemList = make([]model.SingleItemInfo, 0) items := c.Service.Item.Get(data.Param1, data.Param2) + result.ItemList = make([]model.SingleItemInfo, len(items)) for _, itemData := range items { - itemInfo := model.SingleItemInfo{ + + result.ItemList = append(result.ItemList, model.SingleItemInfo{ ItemId: itemData.ItemId, ItemCnt: uint32(itemData.ItemCnt), LeftTime: ItemDefaultLeftTime, - } - if itemInfo.ItemCnt > 0 { - result.ItemList = append(result.ItemList, itemInfo) - } + }) } return result, 0 } diff --git a/logic/controller/login_main.go b/logic/controller/login_main.go index 5f30899c3..f80673203 100644 --- a/logic/controller/login_main.go +++ b/logic/controller/login_main.go @@ -49,7 +49,7 @@ func (h Controller) Login(data *user.MAIN_LOGIN_IN, c gnet.Conn) (result *user.L currentPlayer.Service = service.NewUserService(data.Head.UserID) currentPlayer.Info = currentPlayer.Service.Info.SetLogin() - share.ShareManager.SetUserOnline(data.Head.UserID, h.Port) //设置用户登录服务器 + share.ShareManager.SetUserOnline(data.Head.UserID, h.UID) //设置用户登录服务器 if currentPlayer.Info == nil { defer c.Close() return diff --git a/logic/main.go b/logic/main.go index e86a6843f..e29a40b0c 100644 --- a/logic/main.go +++ b/logic/main.go @@ -102,7 +102,7 @@ func main() { // if cool.Config.GameOnlineID == 2 { //只分析1服务器的 // go PprofWeb() // } - go PprofWeb() + //go PprofWeb() go monitorMemAndQuit() fmt.Println("Process start, pid:", os.Getpid()) diff --git a/logic/server.go b/logic/server.go index 04828b5d6..6587a30bc 100644 --- a/logic/server.go +++ b/logic/server.go @@ -63,6 +63,8 @@ func Start() { if cool.Config.ServerInfo.IsDebug == 1 { g.DB().SetDebug(true) + + go PprofWeb() } port, err := determinePort(cool.Config.ServerInfo.CanPort) @@ -78,7 +80,8 @@ func Start() { rpcClient := rpc.StartClient(serverID, uint32(port), server) //连接rpc controller.Maincontroller.RPCClient = rpcClient //将RPC赋值Start - controller.Maincontroller.Port = uint32(port) //赋值服务器ID + + controller.Maincontroller.UID = uint32(100000*serverID + uint32(port)) //赋值服务器ID controller.Init(true) xmlres.Initfile() diff --git a/logic/service/player/Monster.go b/logic/service/player/Monster.go index 5903ebfcb..8d63e3b85 100644 --- a/logic/service/player/Monster.go +++ b/logic/service/player/Monster.go @@ -3,7 +3,6 @@ package player import ( "blazing/common/utils" "blazing/modules/config/model" - "blazing/modules/config/service" "sync/atomic" "time" @@ -38,10 +37,6 @@ func (p *Player) GenMonster() { return } - mapinfo := service.NewMapService().GetData(p.Info.MapID) - if mapinfo == nil { - return - } var oldnum, newNum int var replce []int p.monsters, oldnum, newNum = replaceOneNumber(p.monsters) @@ -56,7 +51,11 @@ func (p *Player) GenMonster() { p.Data[oldnum] = OgrePetInfo{} //切地图清空 for _, i := range replce { - ogreconfig := service.NewMapPitService().GetData(p.Info.MapID, uint32(i)) + + ogreconfig, ok := p.GetSpace().PitS.Load(i) //service.NewMapPitService().GetData(p.Info.MapID, uint32(i)) + if !ok { + continue + } for _, v := range ogreconfig { diff --git a/logic/service/space/space.go b/logic/service/space/space.go index fb4bf4d47..f05468347 100644 --- a/logic/service/space/space.go +++ b/logic/service/space/space.go @@ -12,6 +12,7 @@ import ( "blazing/logic/service/common" "blazing/logic/service/space/info" + "blazing/modules/config/model" "blazing/modules/config/service" infomodel "blazing/modules/player/model" @@ -44,7 +45,8 @@ type Space struct { TimeBoss info.S2C_2022 //Weather uint32 IsTime bool - //CanWeather uint32 + + PitS *csmap.CsMap[int, []model.MapPit] } // NewSyncMap 创建一个新的玩家同步map @@ -143,20 +145,40 @@ func (ret *Space) init() { maphot[ret.Super] = &MapTip{} maphot[ret.Super].TipInfoS = make(map[uint32]*TipInfo, 0) } - _, ok = maphot[ret.Super].TipInfoS[ret.ID] - if !ok { - tips := &TipInfo{} - r := service.NewMapService().GetData(ret.ID) - if r != nil { - tips.Diao = service.NewMapService().GetData(ret.ID).DropItemIds + + tips := &TipInfo{} + r := service.NewMapService().GetData(ret.ID) + if r != nil { + tips.Diao = service.NewMapService().GetData(ret.ID).DropItemIds + } + + pits := service.NewMapPitService().GetDataALL(ret.ID) + ret.PitS = csmap.New[int, []model.MapPit]() + + for _, v := range pits { + + tips.Pet = append(tips.Pet, v.RefreshID...) + for _, vp := range v.Pos { + t, ok := ret.PitS.Load(vp) + if ok { + t = append(t, v) + ret.PitS.Store(vp, t) + } else { + ret.PitS.Store(vp, []model.MapPit{v}) + } + } - tips.Pet = service.NewMapPitService().GetDataALL(ret.ID) - tips.Talk = service.NewTalkConfigService().GetTip(ret.ID) - tips.Boss = service.NewMapNodeService().GetTip(ret.ID) - maphot[ret.Super].TipInfoS[ret.ID] = tips } + + tips.Pet = lo.Union(tips.Pet) + tips.Talk = service.NewTalkConfigService().GetTip(ret.ID) + tips.Boss = service.NewMapNodeService().GetTip(ret.ID) + maphot[ret.Super].TipInfoS[ret.ID] = tips + ret.Name = v.Name + + //ogreconfig := service.NewMapPitService().GetData(ret.ID, uint32(i)) break } diff --git a/modules/base/service/base_sys_role.go b/modules/base/service/base_sys_role.go index 588c8391d..59c4a8de1 100644 --- a/modules/base/service/base_sys_role.go +++ b/modules/base/service/base_sys_role.go @@ -77,7 +77,7 @@ func (s *BaseSysRoleService) GetByUser(userId uint) []string { ) res, _ := cool.DBM(baseSysUserRole).Where("userId", userId).Array("roleId") for _, v := range res { - roles = append(roles, gconv.String(v)) + roles = append(roles, v.String()) } return roles } diff --git a/modules/config/controller/admin/server.go b/modules/config/controller/admin/server.go index 159443064..94024c6bf 100644 --- a/modules/config/controller/admin/server.go +++ b/modules/config/controller/admin/server.go @@ -36,7 +36,7 @@ func (this *ServerController) Quit(ctx context.Context, req *QuitSReq) (res *coo res = &cool.BaseRes{} serv := service.NewServerService().GetServerID(req.ID) - aa, ok := cool.GetClient(serv.OnlineID*100000 + serv.Port) + aa, ok := cool.GetClient(serv.OnlineID, serv.Port) if ok && aa != nil { //如果已经存在且这个端口已经被存过 aa.QuitSelf(req.Code) } diff --git a/modules/config/service/map_pit.go b/modules/config/service/map_pit.go index 55b6402c2..767aac159 100644 --- a/modules/config/service/map_pit.go +++ b/modules/config/service/map_pit.go @@ -3,8 +3,6 @@ package service import ( "blazing/cool" "blazing/modules/config/model" - - "github.com/samber/lo" ) type MapPitService struct { @@ -22,24 +20,20 @@ func NewMapPitService() *MapPitService { }, } } -func (s *MapPitService) GetData(mapid, pos uint32) []model.MapPit { + +// func (s *MapPitService) GetData(mapid, pos uint32) []model.MapPit { + +// var pet []model.MapPit //一个特性应该是唯一的,但是我们要获取默认随机特性 +// dbm_enable(s.Model).Where("map_id", mapid).Wheref(`pos @> ARRAY[?]::integer[]`, pos).Scan(&pet) + +// return pet + +// } +func (s *MapPitService) GetDataALL(mapid uint32) []model.MapPit { var pet []model.MapPit //一个特性应该是唯一的,但是我们要获取默认随机特性 - dbm_enable(s.Model).Where("map_id", mapid).Wheref(`pos @> ARRAY[?]::integer[]`, pos).Scan(&pet) + dbm_enable(s.Model).Where("map_id", mapid).Scan(&pet) return pet } -func (s *MapPitService) GetDataALL(mapid uint32) []uint32 { - - var pet []model.MapPit //一个特性应该是唯一的,但是我们要获取默认随机特性 - dbm_enable(s.Model).Where("map_id", mapid).Scan(&pet) - var ret []uint32 - for _, v := range pet { - - ret = append(ret, v.RefreshID...) - } - - return lo.Union(ret) - -} diff --git a/modules/config/service/server.go b/modules/config/service/server.go index 5ae2ec572..6a6e582f3 100644 --- a/modules/config/service/server.go +++ b/modules/config/service/server.go @@ -29,7 +29,7 @@ func NewServerService() *ServerService { var rr []g.MapStrAny r, _ := gconv.Map(data)["list"].(gdb.Result) for i := 0; i < len(r); i++ { - t, ok := cool.GetClient(10000*gconv.Uint32(r[i].Map()["online_id"])+gconv.Uint32(r[i].Map()["port"])) + t, ok := cool.GetClient(gconv.Uint32(r[i].Map()["online_id"]), gconv.Uint32(r[i].Map()["port"])) // tt.Friends = v.Friends subm := r[i].GMap() diff --git a/modules/dict/service/dict_info.go b/modules/dict/service/dict_info.go index 8011270e4..f41553fec 100644 --- a/modules/dict/service/dict_info.go +++ b/modules/dict/service/dict_info.go @@ -30,7 +30,11 @@ func (s *DictInfoService) Data(ctx context.Context, types []string) (data interf dictInfoModel = model.NewDictInfo() dictTypeModel = model.NewDictType() ) - mType := cool.DBM(dictTypeModel) + mType := cool.DBM(dictTypeModel).Cache(gdb.CacheOption{ + // Duration: time.Hour, + + Force: false, + }) // 如果types不为空, 则查询指定类型的数据 if len(types) > 0 { mType = mType.Where("key in (?)", types) diff --git a/modules/player/service/info.go b/modules/player/service/info.go index 9b73d54e9..cf522c577 100644 --- a/modules/player/service/info.go +++ b/modules/player/service/info.go @@ -160,7 +160,7 @@ func (s *InfoService) Kick(id uint32) error { return err } - cl, ok := cool.GetClient(useid1) + cl, ok := cool.GetClientOnly(useid1) if ok { err := cl.KickPerson(id) //实现指定服务器踢人 if err != nil { diff --git a/modules/player/service/item.go b/modules/player/service/item.go index de883ad6c..2d11ccfe3 100644 --- a/modules/player/service/item.go +++ b/modules/player/service/item.go @@ -22,7 +22,7 @@ func (s *ItemService) Get(min, max uint32) []model.Item { s.dbm(s.Model).Where(g.Map{ "item_id <=": max, "item_id >=": min, - }).Scan(&ttt) + }).Where("item_cnt >", 0).Scan(&ttt) return ttt