diff --git a/backend/internal/handler/admin/account_handler.go b/backend/internal/handler/admin/account_handler.go index bfa46de05b..eb9c370d7f 100644 --- a/backend/internal/handler/admin/account_handler.go +++ b/backend/internal/handler/admin/account_handler.go @@ -8,7 +8,6 @@ import ( "encoding/json" "errors" "fmt" - "log/slog" "net/http" "strconv" "strings" @@ -370,19 +369,7 @@ func (h *AccountHandler) List(c *gin.Context) { } } if len(accountGroups) > 0 { - var affinityErr error - affinityClients, affinityErr = h.gatewayCache.GetAccountAffinityClientsBatch(c.Request.Context(), accountGroups, service.ClientAffinityTTL) - if affinityErr != nil { - slog.Error("GetAccountAffinityClientsBatch failed", - "error", affinityErr, - "account_count", len(accountGroups), - ) - } else { - slog.Info("GetAccountAffinityClientsBatch success", - "account_count", len(accountGroups), - "result_count", len(affinityClients), - ) - } + affinityClients, _ = h.gatewayCache.GetAccountAffinityClientsBatch(c.Request.Context(), accountGroups, service.ClientAffinityTTL) } } diff --git a/backend/internal/repository/gateway_cache.go b/backend/internal/repository/gateway_cache.go index a226e7e435..8aca561ae2 100644 --- a/backend/internal/repository/gateway_cache.go +++ b/backend/internal/repository/gateway_cache.go @@ -41,6 +41,16 @@ func NewGatewayCache(rdb *redis.Client) service.GatewayCache { return &gatewayCache{rdb: rdb} } +// ensureScriptLoaded 确保 Lua 脚本已加载到 Redis 服务器的脚本缓存中。 +// Pipeline 中的 Script.Run 只发送 EVALSHA,如果 Redis 重启过导致脚本缓存丢失, +// EVALSHA 会返回 NOSCRIPT 错误。此方法提前加载脚本以避免该问题。 +func ensureScriptLoaded(ctx context.Context, rdb *redis.Client, script *redis.Script) { + exists, err := script.Exists(ctx, rdb).Result() + if err != nil || len(exists) == 0 || !exists[0] { + _ = script.Load(ctx, rdb).Err() + } +} + // buildSessionKey 构建 session key,包含 groupID 实现分组隔离 // 格式: sticky_session:{groupID}:{sessionHash} func buildSessionKey(groupID int64, sessionHash string) string { @@ -125,6 +135,8 @@ func (c *gatewayCache) GetAccountAffinityCountBatch(ctx context.Context, groupID now := time.Now().Unix() expireThreshold := now - int64(ttl.Seconds()) + ensureScriptLoaded(ctx, c.rdb, getAffinityCountScript) + pipe := c.rdb.Pipeline() cmds := make([]*redis.Cmd, len(accountIDs)) for i, accID := range accountIDs { @@ -166,6 +178,8 @@ func (c *gatewayCache) GetAccountAffinityClientsBatch(ctx context.Context, accou } } + ensureScriptLoaded(ctx, c.rdb, getAffinityClientsScript) + pipe := c.rdb.Pipeline() cmds := make([]*redis.Cmd, len(queries)) for i, q := range queries {