Nodejs連接redis
目前Nodejs端使用redis模塊對redis服務進行連接,代碼如下:
var redisClient = redis.createClient(config.redisAuth);
redisClient.on("error", function (err) {
redisClient.quit()
logger.error("Error " + err);
redisClient = redis.createClient(config.redisAuth);
});
module.exports = redisClient;
當redis發生error的時候,首先是quit了這個連接,然後再創建一個新的連接。
這樣寫出現了一個問題,就是當發生error然後連接quit了之後,該連接並沒有像預想中的去重新創建新連接去連接,
所以之後使用 redisClient 去set或者get的時候就會報錯,此時redis的操作無法再正常進行,除非重啓服務器重置連接。
當初這麼寫是爲了保證redis鏈接在異常情況下保證能重連,現在看來這種方式是有問題的。
查看官方文檔,確定redis庫是有完善的自動重連機制的,所以以後這塊我們就不做處理了。
redisClient.on("error", function (err) {
logger.error("Error " + err);
});
但並不能保證就一定沒問題了,所以這裏準備加入redis錯誤告警,對redis異常進行監控。
redisClient.on("error", function (err) {
report('RedisError');
logger.error("Error " + err);
});
var client = redis.createClient({
retry_strategy: function (options) {
if (options.error.code === 'ECONNREFUSED') {
// End reconnecting on a specific error and flush all commands with a individual error
report('連接被拒絕');
}
if (options.times_connected > 10) {
report('重試連接超過十次');
}
// reconnect after
return Math.max(options.attempt * 100, 3000);
}
});
在redisClient初始化時,加入 retry_strategy 配置, 對連接的異常進行處理。
此方法如果返回 數字 類型比如 1000, 則該連接 會在 1秒後重新連接。如果返回非數字類型或者是 Error類型,則中斷重連!!(所以必須返回數字)。
這裏還有一個值得注意地方,
當redis斷開連接或者連不上的時候,會拋出一個異常,如果nodejs程序沒有顯示捕獲這個異常進行處理,那麼nodejs進程就會退出,所以需要如下類似的代碼才能保證redis斷開後重連。
function uncaughtExceptionHandler(err){
if(err && err.code == 'ECONNREFUSED'){
//do someting
}else{
process.exit(1);
}
}
process.on('uncaughtException', uncaughtExceptionHandler);