From ee2a87988be5f2e46192363363fccdf2bcc7a0c8 Mon Sep 17 00:00:00 2001 From: hahwu <31872165+hahwu@users.noreply.github.com> Date: Thu, 13 Nov 2025 10:40:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=AD=E7=BA=BF=E9=87=8D=E8=BF=9E=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/server/db/Mysql.go | 57 ++++++++++++++++++++++++++++++++---- src/server/db/Redis.go | 47 +++++++++++++++++++++++++++-- src/server/game/FriendMgr.go | 1 - 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/src/server/db/Mysql.go b/src/server/db/Mysql.go index 309d5cdc..43f835ca 100644 --- a/src/server/db/Mysql.go +++ b/src/server/db/Mysql.go @@ -1,7 +1,6 @@ package db import ( - //"database/sql" "fmt" "reflect" "server/GoUtil" @@ -9,6 +8,8 @@ import ( "server/conf" "server/pkg/github.com/name5566/leaf/log" "strings" + "sync" + "time" // "server/game" _ "github.com/go-sql-driver/mysql" @@ -23,14 +24,60 @@ type user struct { } var SqlDb *sqlx.DB +var sqlDbMu sync.Mutex + +// 封装创建连接 +func connectMySQL() (*sqlx.DB, error) { + MysqlPwd, _ := GoUtil.Decrypt(conf.Server.MySqlPwd) + connect := fmt.Sprintf("%s:%s@(%s:%s)/%s", conf.Server.MySqlUsr, MysqlPwd, conf.Server.MySqlAddr, conf.Server.MySqlPort, conf.Server.DbName) + db, err := sqlx.Connect("mysql", connect) + if err != nil { + return nil, err + } + db.SetMaxOpenConns(20) + return db, nil +} func InitDB() { //"用户名:密码@[连接方式](主机名:端口号)/数据库名" - MysqlPwd, _ := GoUtil.Decrypt(conf.Server.MySqlPwd) - connect := fmt.Sprintf("%s:%s@(%s:%s)/%s", conf.Server.MySqlUsr, MysqlPwd, conf.Server.MySqlAddr, conf.Server.MySqlPort, conf.Server.DbName) - SqlDb = sqlx.MustConnect("mysql", connect) // 设置连接数据库的参数 - SqlDb.SetMaxOpenConns(20) // 设置最大打开的连接数 + db, err := connectMySQL() + if err != nil { + log.Debug("connect mysql failed: %v", err) + return + } + SqlDb = db log.Debug("connect mysql success") + + // 定时检测与重连 + go func() { + ticker := time.NewTicker(time.Second) + defer ticker.Stop() + for range ticker.C { + sqlDbMu.Lock() + cur := SqlDb + sqlDbMu.Unlock() + if cur == nil || cur.Ping() != nil { + log.Debug("mysql ping failed, start reconnect") + ReconnectDB() + } + } + }() +} + +// 自动重连 +func ReconnectDB() { + sqlDbMu.Lock() + defer sqlDbMu.Unlock() + newDb, err := connectMySQL() + if err != nil { + log.Debug("mysql reconnect failed: %v", err) + return + } + if SqlDb != nil { + _ = SqlDb.Close() + } + SqlDb = newDb + log.Debug("mysql reconnect success") } func SeriesTransaction(sqlstrs []string, params [][]any) (err error) { diff --git a/src/server/db/Redis.go b/src/server/db/Redis.go index 850f2ec0..820aa2e9 100644 --- a/src/server/db/Redis.go +++ b/src/server/db/Redis.go @@ -4,6 +4,7 @@ import ( "context" "server/conf" "server/pkg/github.com/name5566/leaf/log" + "sync" "time" "github.com/redis/go-redis/v9" @@ -11,22 +12,62 @@ import ( var ctx = context.Background() +var redisMu sync.Mutex + var Rdb *redis.Client -func InitRedis() { +// 封装创建连接 +func connectRedis() (*redis.Client, error) { rdb := redis.NewClient(&redis.Options{ Addr: conf.Server.RedisAddr + ":" + conf.Server.RedisPort, Password: conf.Server.RedisPwd, // no password set DB: conf.Server.RedisDb, }) + if _, err := rdb.Ping(ctx).Result(); err != nil { + return nil, err + } + return rdb, nil +} - _, err := rdb.Ping(ctx).Result() +func InitRedis() { + rdb, err := connectRedis() if err != nil { log.Debug("连接redis出错,错误信息:%v", err) return } - log.Debug("成功连接redis") Rdb = rdb + log.Debug("成功连接redis") + + // 定时检测与重连 + go func() { + ticker := time.NewTicker(time.Minute) + defer ticker.Stop() + for range ticker.C { + redisMu.Lock() + cur := Rdb + redisMu.Unlock() + if cur == nil || cur.Ping(ctx).Err() != nil { + log.Debug("redis ping failed, start reconnect") + ReconnectRedis() + } + } + }() +} + +// 重连 +func ReconnectRedis() { + redisMu.Lock() + defer redisMu.Unlock() + newRdb, err := connectRedis() + if err != nil { + log.Debug("redis reconnect failed: %v", err) + return + } + if Rdb != nil { + _ = Rdb.Close() + } + Rdb = newRdb + log.Debug("redis reconnect success") } func RedisSetKey(key string, value string, expiration time.Duration) { diff --git a/src/server/game/FriendMgr.go b/src/server/game/FriendMgr.go index 6d391bf8..033029a3 100644 --- a/src/server/game/FriendMgr.go +++ b/src/server/game/FriendMgr.go @@ -25,7 +25,6 @@ type FirendData struct { } func (f *FriendMgr) Init() { - gob.Register(card.CardInfo{}) gob.Register(item.Item{}) gob.Register([]*item.Item{}) // 注册 []*item.Item 类型