[英]NodeJS Redis - Reconnect In Background
我的情况是 - 我正在尝试通过 REDIS 密钥检索资源。 如果密钥不存在,则从 API 获取它。
遇到一个问题,如果 Redis 连接中断,或者我无法从启动时连接到 Redis,那么 nodejs 库 ('redis') 将继续尝试重新连接。 它阻止我通过 API 获取我需要的信息,因为重试逻辑将接管并且不会继续获取所需的信息。
我希望此功能在后台运行 - 可能吗?
意思是,如果 Redis 关闭/无法从 NodeJs 连接到 REDIS,那么它将尝试重新连接。 但是,当它关闭并且应用程序将尝试定期重新连接时,我希望能够通过备份计划(即通过 API)获取数据,如上所述。
任何关于这种情况的指示将不胜感激 - 在此先感谢您。
您可以在 redis-connection 周围创建一个包装器/代理,以确保 redis 已连接到所有 redis 操作。 如果不是,您可以抛出错误(您可以在调用者中处理)或返回未定义。
基本上,您可以侦听ready
和error
事件并更新该包装器内的status
标志,以便始终了解当前的连接状态。
现在,这肯定会涵盖初始连接不成功或呼叫之间发生断开连接的情况。 问题是在您成功检查status
标志后发生断开连接的罕见情况。 为了解决这个问题,您可以定义 redis 调用的最大等待时间,并在达到超时时返回/抛出错误并忽略 redis 结果。 以下是一些基本代码,可以帮助您入门:
class RedisService {
isConnected = false;
client;
constructor() {
this.client = redis.createClient();
this.client.get = promisify(this.client.get).bind(this.client);
this.client.set = promisify(this.client.set).bind(this.client);
this.attachHandlers();
}
attachHandlers() {
this.client.on("ready", () => {
this.isConnected = true;
});
this.client.on("error", (err) => {
this.isConnected = false;
console.log(err);
});
}
async tryGet(key) {
if (!this.isConnected) {
return undefined; // or throw an error
}
return Promise.race([this.client.get(key), this.wait()]);
}
async trySet(key, val) {
if (!this.isConnected) {
return undefined; // or throw an error
}
return Promise.race([this.client.set(key, val), this.wait()]);
}
wait(ms = 200) {
return new Promise(resolve => {
setTimeout(resolve, ms);
})
}
}
然后在您的来电者中,您可以执行以下操作:
async someMethodThatCallsRedisOrApi() {
let result;
try {
result = await redisService.tryGet('testkey');
} catch (e) {
console.log(e);
}
if (!result) {
result = apiService.get(...); // call the actual api to get the result
await redisService.trySet('testkey', result);
}
res.json(result)
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.