简体   繁体   English

如何配置节点 Redis 客户端在连接失败时立即抛出错误? [阅读详情]

[英]How to configure Node Redis client to throw errors immediately, when connection has failed? [READ DETAILS]

I am using Node Redis with this config:我正在使用带有此配置的节点 Redis:

import redis from "redis";
import { promisify } from "util";
import config from "../../appConfig";

const redisUrl = config.REDIS_URL;
const [host, port] = redisUrl.substr(8).split(":");
const RedisClient = redis.createClient({ host: host, port: Number(port) });
RedisClient.on("error", (err) => {
    logger.error(err);
});
const GetAsync = promisify(RedisClient.get).bind(RedisClient);
const SetAsync = promisify(RedisClient.set).bind(RedisClient);

export { RedisClient, GetAsync, SetAsync };

I have some code which first tries reading from Redis and if that fails, tries reading from MongoDB inside a catch block.我有一些代码首先尝试从 Redis 读取,如果失败,则尝试从 catch 块内的 MongoDB 读取。 Something like this:像这样的东西:

try {
    userId = await GetAsync(idKeyStr);
} catch(err) {
    userId = await GetFromMongoDB();
}

My problem is that when the connection fails, the code just gets stuck at userId = await GetAsync(idKeyStr) .我的问题是,当连接失败时,代码会卡在userId = await GetAsync(idKeyStr) No exception is being thrown so that the code moves into the catch block.没有抛出异常,因此代码移动到 catch 块中。 The default time till which the client attempts to reconnect is 1 hour.客户端尝试重新连接的默认时间为 1 小时。 If within that 1 hour, the server comes up, it will reconnect and the request which was stuck will finally get handled.如果在这 1 小时内,服务器启动,它将重新连接,最终被卡住的请求将得到处理。 If it doesnt come up, that request will just be stuck for 1 hour.如果它没有出现,该请求将仅停留 1 小时。

If I throw an error from the callback for error event, the application just stops, because of unhandled exception.如果我从error事件的回调中抛出错误,应用程序就会停止,因为未处理的异常。

I found the retry_strategy option for the createClient method here: https://github.com/NodeRedis/node-redis This is the example given on that page:我在这里找到了createClient方法的retry_strategy选项: https://github.com/NodeRedis/node-redis这是该页面上给出的示例:

const client = redis.createClient({
  retry_strategy: function(options) {
    if (options.error && options.error.code === "ECONNREFUSED") {
      // End reconnecting on a specific error and flush all commands with
      // a individual error
      return new Error("The server refused the connection");
    }
    if (options.total_retry_time > 1000 * 60 * 60) {
      // End reconnecting after a specific timeout and flush all commands
      // with a individual error
      return new Error("Retry time exhausted");
    }
    if (options.attempt > 10) {
      // End reconnecting with built in error
      return undefined;
    }
    // reconnect after
    return Math.min(options.attempt * 100, 3000);
  },
});

To throw an error immediately, I modified this to:为了立即抛出错误,我将其修改为:

const client = redis.createClient({
      retry_strategy: function() {
          return new Error("The server refused the connection");
      },
    });

But this stops the retries altogether, so even when the server comes up, the client has stopped connection attempts so it never reconnects.但这完全停止了重试,因此即使服务器启动,客户端也停止了连接尝试,因此它永远不会重新连接。

How can I configure it so that the client continues to reconnect but any issued commands fail fast, so that my other code continues execution?如何配置它以使客户端继续重新连接但任何发出的命令都会快速失败,以便我的其他代码继续执行?

Setting enable_offline_queue to false did the trick.enable_offline_queue设置为false就可以了。 Found lots of similar questions but none mentioned this:发现很多类似的问题,但没有人提到这一点:

Nodejs set timeout for Redis requests Nodejs为Redis请求设置超时

What's the default timeout of ioredis send command for any redis call 对于任何 redis 调用,ioredis 发送命令的默认超时是多少

How to set read timeout on node redis client? 如何在节点 redis 客户端上设置读取超时?

Finally got this solution from here: https://github.com/NodeRedis/node-redis/issues/789#issuecomment-373270272终于从这里得到了这个解决方案: https://github.com/NodeRedis/node-redis/issues/789#issuecomment-373270272

Do keep in mind that, with enable_offline_queue set to false, the commands that you issue while there's some connection issue with the server will never be executed.请记住,在enable_offline_queue设置为 false 的情况下,您在与服务器存在连接问题时发出的命令将永远不会被执行。

For anyone using this in 2022, the configuration name is now disableOfflineQueue .对于在 2022 年使用它的任何人,配置名称现在是disableOfflineQueue It is set to false by default, so you have to set it to true in creatClient .它默认设置为 false,因此您必须在creatClient其设置为 true。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM