From 4ad384b01a168c113da8649f1036ace62ecf401c Mon Sep 17 00:00:00 2001 From: shanshanzhong Date: Sun, 23 Nov 2025 23:39:30 -0800 Subject: [PATCH] =?UTF-8?q?fix(redis):=20=E4=BF=AE=E5=A4=8D=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E8=AE=BE=E7=BD=AE=E5=92=8C=E6=B8=85=E9=99=A4=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复Redis缓存设置未设置TTL的问题,使用节点拉取间隔加60秒作为TTL 修复ClearServerAllCache中重复添加keys的问题 修复ClearServerCache中未使用cursor参数的问题 优化ClearServerAllCache以支持清除多种前缀的缓存 --- .../public/user/bindInviteCodeHandler.go | 36 ++++++------ internal/logic/server/getServerConfigLogic.go | 4 +- .../logic/server/getServerUserListLogic.go | 10 ++-- internal/model/node/model.go | 57 ++++++++++--------- 4 files changed, 57 insertions(+), 50 deletions(-) diff --git a/internal/handler/public/user/bindInviteCodeHandler.go b/internal/handler/public/user/bindInviteCodeHandler.go index 7fe249a..fa36150 100644 --- a/internal/handler/public/user/bindInviteCodeHandler.go +++ b/internal/handler/public/user/bindInviteCodeHandler.go @@ -1,25 +1,25 @@ package user import ( - "github.com/gin-gonic/gin" - logic "github.com/perfect-panel/server/internal/logic/public/user" - "github.com/perfect-panel/server/internal/svc" - "github.com/perfect-panel/server/internal/types" - "github.com/perfect-panel/server/pkg/result" + "github.com/gin-gonic/gin" + logic "github.com/perfect-panel/server/internal/logic/public/user" + "github.com/perfect-panel/server/internal/svc" + "github.com/perfect-panel/server/internal/types" + "github.com/perfect-panel/server/pkg/result" ) func BindInviteCodeHandler(svcCtx *svc.ServiceContext) func(c *gin.Context) { - return func(c *gin.Context) { - var req types.BindInviteCodeRequest - _ = c.ShouldBind(&req) - validateErr := svcCtx.Validate(&req) - if validateErr != nil { - result.ParamErrorResult(c, validateErr) - return - } + return func(c *gin.Context) { + var req types.BindInviteCodeRequest + _ = c.ShouldBind(&req) + validateErr := svcCtx.Validate(&req) + if validateErr != nil { + result.ParamErrorResult(c, validateErr) + return + } - l := logic.NewBindInviteCodeLogic(c.Request.Context(), svcCtx) - err := l.BindInviteCode(&req) - result.HttpResult(c, nil, err) - } -} \ No newline at end of file + l := logic.NewBindInviteCodeLogic(c.Request.Context(), svcCtx) + err := l.BindInviteCode(&req) + result.HttpResult(c, nil, err) + } +} diff --git a/internal/logic/server/getServerConfigLogic.go b/internal/logic/server/getServerConfigLogic.go index 94221a9..61366a3 100644 --- a/internal/logic/server/getServerConfigLogic.go +++ b/internal/logic/server/getServerConfigLogic.go @@ -4,6 +4,7 @@ import ( "encoding/base64" "encoding/json" "fmt" + "time" "github.com/gin-gonic/gin" "github.com/perfect-panel/server/internal/model/node" @@ -90,7 +91,8 @@ func (l *GetServerConfigLogic) GetServerConfig(req *types.GetServerConfigRequest } etag := tool.GenerateETag(c) l.ctx.Header("ETag", etag) - if err = l.svcCtx.Redis.Set(l.ctx, cacheKey, c, -1).Err(); err != nil { + ttl := time.Second * time.Duration(l.svcCtx.Config.Node.NodePullInterval+60) + if err = l.svcCtx.Redis.Set(l.ctx, cacheKey, c, ttl).Err(); err != nil { l.Errorw("[GetServerConfig] redis set error", logger.Field("error", err.Error())) } // Check If-None-Match header diff --git a/internal/logic/server/getServerUserListLogic.go b/internal/logic/server/getServerUserListLogic.go index 70ea51f..2a1df57 100644 --- a/internal/logic/server/getServerUserListLogic.go +++ b/internal/logic/server/getServerUserListLogic.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "strings" + "time" "github.com/gin-gonic/gin" "github.com/perfect-panel/server/internal/model/node" @@ -121,10 +122,11 @@ func (l *GetServerUserListLogic) GetServerUserList(req *types.GetServerUserListR val, _ := json.Marshal(resp) etag := tool.GenerateETag(val) l.ctx.Header("ETag", etag) - err = l.svcCtx.Redis.Set(l.ctx, cacheKey, string(val), -1).Err() - if err != nil { - l.Errorw("[ServerUserListCacheKey] redis set error", logger.Field("error", err.Error())) - } + ttl := time.Second * time.Duration(l.svcCtx.Config.Node.NodePullInterval+60) + err = l.svcCtx.Redis.Set(l.ctx, cacheKey, string(val), ttl).Err() + if err != nil { + l.Errorw("[ServerUserListCacheKey] redis set error", logger.Field("error", err.Error())) + } // Check If-None-Match header if match := l.ctx.GetHeader("If-None-Match"); match == etag { return nil, xerr.StatusNotModified diff --git a/internal/model/node/model.go b/internal/model/node/model.go index 0fbe274..bc39366 100644 --- a/internal/model/node/model.go +++ b/internal/model/node/model.go @@ -130,7 +130,7 @@ func (m *customServerModel) ClearNodeCache(ctx context.Context, params *FilterNo return err } if len(keys) > 0 { - cacheKeys = append(keys, keys...) + cacheKeys = append(cacheKeys, keys...) } cursor = newCursor if cursor == 0 { @@ -152,11 +152,11 @@ func (m *customServerModel) ClearServerCache(ctx context.Context, serverId int64 var cacheKeys []string cacheKeys = append(cacheKeys, fmt.Sprintf("%s%d", ServerUserListCacheKey, serverId)) var cursor uint64 - for { - keys, newCursor, err := m.Cache.Scan(ctx, 0, fmt.Sprintf("%s%d*", ServerConfigCacheKey, serverId), 100).Result() - if err != nil { - return err - } + for { + keys, newCursor, err := m.Cache.Scan(ctx, cursor, fmt.Sprintf("%s%d*", ServerConfigCacheKey, serverId), 100).Result() + if err != nil { + return err + } if len(keys) > 0 { cacheKeys = append(cacheKeys, keys...) } @@ -174,27 +174,30 @@ func (m *customServerModel) ClearServerCache(ctx context.Context, serverId int64 } func (m *customServerModel) ClearServerAllCache(ctx context.Context) error { - var cursor uint64 - var keys []string - prefix := ServerConfigCacheKey + "*" - for { - scanKeys, newCursor, err := m.Cache.Scan(ctx, cursor, prefix, 999).Result() - if err != nil { - m.Logger.Error(ctx, fmt.Sprintf("ClearServerAllCache err:%v", err)) - break - } - m.Logger.Info(ctx, fmt.Sprintf("ClearServerAllCache query keys:%v", scanKeys)) - keys = append(keys, scanKeys...) - cursor = newCursor - if cursor == 0 { - break - } - } - if len(keys) > 0 { - m.Logger.Info(ctx, fmt.Sprintf("ClearServerAllCache keys:%v", keys)) - return m.Cache.Del(ctx, keys...).Err() - } - return nil + var cursor uint64 + var keys []string + prefixes := []string{ServerConfigCacheKey + "*", ServerUserListCacheKey + "*"} + for _, prefix := range prefixes { + cursor = 0 + for { + scanKeys, newCursor, err := m.Cache.Scan(ctx, cursor, prefix, 999).Result() + if err != nil { + m.Logger.Error(ctx, fmt.Sprintf("ClearServerAllCache err:%v", err)) + break + } + m.Logger.Info(ctx, fmt.Sprintf("ClearServerAllCache query keys:%v", scanKeys)) + keys = append(keys, scanKeys...) + cursor = newCursor + if cursor == 0 { + break + } + } + } + if len(keys) > 0 { + m.Logger.Info(ctx, fmt.Sprintf("ClearServerAllCache keys:%v", keys)) + return m.Cache.Del(ctx, keys...).Err() + } + return nil } // InSet 支持多值 OR 查询