簡體   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