为了账号安全,请及时绑定邮箱和手机立即绑定

NodeJS Redis - 在后台重新连接

NodeJS Redis - 在后台重新连接

潇潇雨雨 2023-03-24 14:38:16
我的情况是 - 我正在尝试通过 REDIS 密钥检索资源。如果密钥不存在,则从 API 获取它。遇到一个问题,如果 Redis 连接断开或者我无法从启动连接到 Redis,那么 nodejs 库('redis')将继续尝试重新连接。它阻止我通过 API 获取我需要的信息,因为重试逻辑将接管并且不会继续获取所需信息。我希望此功能在后台运行 - 可能吗?意思是,如果 Redis 关闭/无法从 NodeJs 连接到 REDIS,那么它将尝试重新连接。然而,当它关闭并且应用程序将尝试定期重新连接时,我希望能够通过备份计划获取数据,即通过 API,正如我上面提到的。任何关于这种情况的指示将不胜感激 - 在此先感谢您。
查看完整描述

1 回答

?
莫回无

TA贡献1865条经验 获得超7个赞

您可以围绕您的 redis 连接创建一个包装器/代理,以确保所有 redis 操作都连接了 redis。如果不是,您可以抛出一个错误(您可以在调用者中处理)或返回未定义。


基本上,您可以侦听ready和error事件并更新status该包装器内的 - 标志,以便始终了解当前的连接状态。


现在,这肯定会涵盖初始连接不成功或调用之间发生断开连接的情况。问题是在您status成功检查 -flag 后断开连接的罕见情况。要解决这个问题,您可以为 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)

});


查看完整回答
反对 回复 2023-03-24
  • 1 回答
  • 0 关注
  • 154 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信