Arv*_*ran 6 redis node.js 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");
}
Run Code Online (Sandbox Code Playgroud)
但是,使用此代码,如果 redis 不可用,我的应用程序将退出(不应该,因为我没有给出 process.exit() 命令)。
我该如何解决这个问题?
使用 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);
});
Run Code Online (Sandbox Code Playgroud)
Redis 客户端非空并不能保证使用它不会抛出错误。
您可能会遇到基础设施故障,例如 Redis 进程崩溃、内存不足或网络故障。
代码中的错误可能会导致错误,例如 redis 命令的参数无效或丢失。
当然,您应该处理 Redis 客户端错误。
不 nullRedis 客户端出错
它不会给你太多,但它会迫使你每次尝试使用它时都检查 null 。
nullRedis 客户端还具有内置的重新连接和重试机制,如果您在第一次错误后使用它,您将错过这些机制。请参阅 redis 包文档,查找retry_strategy.
请使用您的 Promise 链包装您的 Redis 客户端代码try .. catch ...或.catch在 Promise 链中使用。
请使用retry_strategy.