Redis 服务重启时出现“NOSCRIPT Nomatching script. Please use EVAL”错误

问题描述 投票:0回答:2

我在我的节点 ExpressJS 服务器中将 Redis 与 express-rate-limitrate-limit-redis 一起使用。

我面临的问题是,当我的 Redis 服务器重新启动时(我知道这是不应该发生的事情,但是,我们只是认为它最终可能会发生),它会成功重新连接,但随后在下一个请求到我的服务器,我从 Redis 收到此错误:

NOSCRIPT No matching script. Please use EVAL

我读过一些有关它的信息,我发现我不是唯一一个遇到这个问题的人。

但是我还是没能找到解决办法。

我应该怎样做才能避免这个错误?我有什么选择?

编辑:找到解决方案

所以基本上,当Redis连接时,我通过

redisClient.scriptLoad
Redis客户端功能加载所需的脚本。

文件:

rate-limit.cript.lua

// Script source: https://github.com/wyattjoh/rate-limit-redis/blob/dcb5941c45325a8037bbb257882f745d9ee74b89/src/lib.ts#L58

local totalHits = redis.call("INCR", KEYS[1])
local timeToExpire = redis.call("PTTL", KEYS[1])
if timeToExpire <= 0 or ARGV[1] == "1"
then
    redis.call("PEXPIRE", KEYS[1], tonumber(ARGV[2]))
    timeToExpire = tonumber(ARGV[2])
end
return { totalHits, timeToExpire }

文件:

redis.js
(Redis连接管理)

const loadRateLimitScript = (redisClient) => redisClient.scriptLoad(
  fs.readFileSync(`${__dirname}/../constants/luaScripts/rate-limit-script.lua`, 'utf8')
    .replace(/^\s+/gm, '')
    .trim()
);


class myRedis {

  constructor() {
    const redisClient = createClient({
      url: `redis://${REDIS.HOST}:${REDIS.PORT}`
      , username: REDIS.USERNAME
      , password: REDIS.PASSWORD
    });

    redisClient.on('error', onRedisError);
    redisClient.on('connect', () => {
      loadRateLimitScript(redisClient);
    });
    redisClient.on('reconnecting', onRedisReconnecting);
    redisClient.on('ready', onRedisReady);
    redisClient.on('end', onRedisEnd);

    this.redisClient = redisClient;
  }
}
node.js express redis node-redis express-rate-limit
2个回答
2
投票

NOSCRIPT 没有匹配的脚本。请使用EVAL

这意味着您正在使用

EVALSHA
来运行预加载的脚本。但是,该脚本不存在。因为当Redis重新启动时,所有预加载的脚本都会被删除。

在您的情况下,rate-limit-redis可能使用了一些预加载的脚本,并且这些脚本在Redis重新启动时已被删除。因此,您需要查看 rate-limit-redis' 文档来找到重新加载这些脚本的方法 (

SCRIPT LOAD
)。


2
投票

3.9.23 更新: 该问题应在 v3.1.0

中修复

rate-limit-redis
有一个关于此的开放问题,并且开放PR应该可以修复它。

© www.soinside.com 2019 - 2024. All rights reserved.