繁体   English   中英

NodeJS Redis - 在后台重新连接

[英]NodeJS Redis - Reconnect In Background

我的情况是 - 我正在尝试通过 REDIS 密钥检索资源。 如果密钥不存在,则从 API 获取它。

遇到一个问题,如果 Redis 连接中断,或者我无法从启动时连接到 Redis,那么 nodejs 库 ('redis') 将继续尝试重新连接。 它阻止我通过 API 获取我需要的信息,因为重试逻辑将接管并且不会继续获取所需的信息。

我希望此功能在后台运行 - 可能吗?

意思是,如果 Redis 关闭/无法从 NodeJs 连接到 REDIS,那么它将尝试重新连接。 但是,当它关闭并且应用程序将尝试定期重新连接时,我希望能够通过备份计划(即通过 API)获取数据,如上所述。

任何关于这种情况的指示将不胜感激 - 在此先感谢您。

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

基本上,您可以侦听readyerror事件并更新该包装器内的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.

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