node.js - Redis 服务重启时出现 Redis 错误 "NOSCRIPT No matching script. Please use EVAL"

标签 node.js express redis node-redis express-rate-limit

我正在使用 Redis express-rate-limitrate-limit-redis在我的 Node ExpressJS 服务器中。

我面临的问题是,当我的 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;
  }
}

最佳答案

NOSCRIPT No matching script. Please use EVAL

这意味着您正在使用 EVALSHA 运行预加载的脚本。但是,该脚本不存在。因为当Redis重新启动时,所有预加载的脚本都会被删除。

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

关于node.js - Redis 服务重启时出现 Redis 错误 "NOSCRIPT No matching script. Please use EVAL",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74021041/

相关文章:

javascript - 从 Node 模块中的函数返回数据

node.js - 使用 Express 4.x 的 res.cookie 时请求头无法获取 cookie

node.js - 为什么我的 POST 请求在 Node 中不起作用

mysql - 从 MySQL 到 NoSQL 键值存储的数据同步

javascript - 使用 webpack 为浏览器和 Node 构建

node.js - 从输入流 CLI 读取数据 - NodeJS

node.js - .then() 中出现意外的 promise 值

javascript - Node.js EJS 快速验证器

rspec - 当在一个 RSpec 套件中调用多个 with_api() 测试时,Goliath 会破坏 em-synchrony/em-hiredis

php - 基于流的网站 - 使用 memcache(d) 进行优化的选项