From ae1934f7dbc3c721321918793143e05ed0410e16 Mon Sep 17 00:00:00 2001 From: shaw Date: Thu, 5 Feb 2026 22:36:17 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E6=B4=BB=E8=B7=83=E4=BC=9A=E8=AF=9D=E6=95=B0?= =?UTF-8?q?=E5=A7=8B=E7=BB=88=E6=98=BE=E7=A4=BA=E4=B8=BA0=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题原因:Redis Pipeline 执行 Lua 脚本时出现 NOSCRIPT 错误, 因为 redis.NewScript 使用 EVALSHA 执行脚本,当 Redis 重启或 脚本未被缓存时,Pipeline 模式无法自动回退到 EVAL。 解决方案:在 NewSessionLimitCache 初始化时预加载所有 Lua 脚本 到 Redis,确保后续 Pipeline 执行时脚本已被缓存。 --- .../internal/repository/session_limit_cache.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/backend/internal/repository/session_limit_cache.go b/backend/internal/repository/session_limit_cache.go index 3dc89f87..3d57b152 100644 --- a/backend/internal/repository/session_limit_cache.go +++ b/backend/internal/repository/session_limit_cache.go @@ -3,6 +3,7 @@ package repository import ( "context" "fmt" + "log" "strconv" "time" @@ -153,6 +154,21 @@ func NewSessionLimitCache(rdb *redis.Client, defaultIdleTimeoutMinutes int) serv if defaultIdleTimeoutMinutes <= 0 { defaultIdleTimeoutMinutes = 5 // 默认 5 分钟 } + + // 预加载 Lua 脚本到 Redis,避免 Pipeline 中出现 NOSCRIPT 错误 + ctx := context.Background() + scripts := []*redis.Script{ + registerSessionScript, + refreshSessionScript, + getActiveSessionCountScript, + isSessionActiveScript, + } + for _, script := range scripts { + if err := script.Load(ctx, rdb).Err(); err != nil { + log.Printf("[SessionLimitCache] Failed to preload Lua script: %v", err) + } + } + return &sessionLimitCache{ rdb: rdb, defaultIdleTimeout: time.Duration(defaultIdleTimeoutMinutes) * time.Minute,