如果redis不可用,我如何忽略redis?

时间:2015-03-06 02:36:06

标签: node.js redis node-redis

我希望我的应用程序(现在简单地说一个简单的节点文件)即使redis不可用也能正常工作。我无法以正确的方式做到这一点。这就是我尝试过的。

var redis = require('redis');
var redisClient = null;

var getRedisClient = function(){
    if(redisClient){
        return redisClient;
    }

    try {
        redisClient = redis.createClient({connect_timeout : 5000, max_attempts : 1});
        redisClient.on("error", function(err) {
            console.error("Error connecting to redis", err);
            redisClient = null;
        });
        return redisClient;
    } catch(ex){
        console.log("error initialising redis client " + ex);
        return null;
    }
};

try {
    var client = getRedisClient();
    console.log("done!");
} catch (ex){
    console.log("Exception");
}

但是,使用此代码,如果redis不可用,我的应用程序将退出(它不应该因为我没有给出process.exit()命令)。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

检查开始时是否成功连接

使用承诺,您可以保证至少在最初,您能够在指定的时间段内无错误地连接到redis:

const redis = require('redis');
const Promise = require('bluebird');

function getRedisClient(timeoutMs){
    return new Promise((resolve, reject) => {
        const redisClient = redis.createClient();
        const timer = setTimeout(() => reject('timeout'), timeoutMs);
        redisClient.on("ready", () => {
            clearTimeout(timer);
            resolve(redisClient);
        });
        redisClient.on("error", (err) => {
            clearTimeout(timer);
            reject(err);
        });
    });
};

const redisReadyTimeoutMs = 10000;

getRedisClient(redisReadyTimeoutMs)
    .then(redisClient => {
        // the client has connected to redis sucessfully
        return doSomethingUseful();
    }, error => {
        console.log("Unable to connect to redis", error);
    });

您需要正确的错误处理

redis客户端非空, NOT 保证使用它不会抛出错误。

  • 你可能会遇到基础设施不幸,例如崩溃的redis进程,内存不足或网络崩溃。

  • 您的代码中的错误可能会导致错误,例如redis命令的参数无效或缺失。

您应该理所当然地处理redis客户端错误。

发现错误的Redis客户端 null

它不会给你太多但是每次你尝试使用它时它都会强制你检查null。

redis客户端还具有内置的重新连接和重试机制,如果您在第一次出错后null,它将会错过。请参阅redis包文档,查找retry_strategy

DO 使用try .. catch ...包裹您的redis客户端代码或在您的承诺链中使用.catch

DO 使用retry_strategy