【问题标题】:How do I ignore redis if it is not available?如果 redis 不可用,如何忽略它?
【发布时间】:2015-03-06 02:36:06
【问题描述】:

我希望我的应用程序(现在让我们说一个简单的节点文件)能够正常工作,即使 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() 命令)。

我该如何解决这个问题?

【问题讨论】:

  • 我认为您的应用程序退出了,因为它没有什么可做的了。添加服务器什么的。
  • @Farid 不,如果 redis 开启,应用程序不会退出。
  • 当redis不在应用程序存在时,因为它无关。当 redis 开启时,与 redis 服务器有一个持久连接,并且应用程序不会退出,因为连接没有关闭。只有在没有连接/服务器/事件或任何其他类型的 IO 时,节点才会关闭。
  • 所以你是说这段代码没问题?
  • 对我来说看起来不错,但你不知道代码是否完美,直到它在生产中测试......:P

标签: node.js redis node-redis


【解决方案1】:

启动时检查连接是否成功

使用promise,您可以保证至少在最初,您能够在指定的时间段内无错误地连接到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 客户端错误。

不要 null Redis 客户端出错

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

redis 客户端还具有内置的重新连接和重试机制,如果您在第一个错误后null 它会错过这些机制。查看 redis 包文档,查找 retry_strategy

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

使用retry_strategy

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多