当连接失败时,如何配置 Node Redis 客户端以立即抛出错误?[阅读详情] [英] How to configure Node Redis client to throw errors immediately, when connection has failed? [READ DETAILS]
问题描述
我在此配置中使用 Node Redis:
I am using Node Redis with this config:
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 };
我有一些代码首先尝试从 Redis 读取,如果失败,则尝试从 catch 块内的 MongoDB 读取.像这样:
I have some code which first tries reading from Redis and if that fails, tries reading from MongoDB inside a catch block. Something like this:
try {
userId = await GetAsync(idKeyStr);
} catch(err) {
userId = await GetFromMongoDB();
}
我的问题是,当连接失败时,代码会卡在 userId = await GetAsync(idKeyStr)
.没有抛出异常,因此代码移动到 catch 块中.客户端尝试重新连接的默认时间为 1 小时.如果在那 1 小时内,服务器启动,它将重新连接,并最终处理卡住的请求.如果它没有出现,该请求将被卡住 1 小时.
My problem is that when the connection fails, the code just gets stuck at userId = await GetAsync(idKeyStr)
. No exception is being thrown so that the code moves into the catch block. The default time till which the client attempts to reconnect is 1 hour. If within that 1 hour, the server comes up, it will reconnect and the request which was stuck will finally get handled. If it doesnt come up, that request will just be stuck for 1 hour.
如果我从 error
事件的回调中抛出错误,应用程序就会因为未处理的异常而停止.
If I throw an error from the callback for error
event, the application just stops, because of unhandled exception.
我在这里找到了 createClient
方法的 retry_strategy
选项:https://github.com/NodeRedis/node-redis 这是该页面上给出的示例:
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:
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?
推荐答案
将 enable_offline_queue
设置为 false
即可解决问题.发现了很多类似的问题,但没有一个提到这一点:
Setting enable_offline_queue
to false
did the trick. Found lots of similar questions but none mentioned this:
什么是任何redis调用的ioredis发送命令的默认超时时间
终于从这里得到了这个解决方案:https://github.com/NodeRedis/node-redis/issues/789#issuecomment-373270272
Finally got this solution from here: https://github.com/NodeRedis/node-redis/issues/789#issuecomment-373270272
请记住,如果 enable_offline_queue
设置为 false,您在服务器出现连接问题时发出的命令将永远不会执行.
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.
这篇关于当连接失败时,如何配置 Node Redis 客户端以立即抛出错误?[阅读详情]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!