nodejs to redis ошибка ECONNRESET
Для наших соединений Node.js с Redis мы используем модуль Redis npm.
Время от времени мы получаем следующую ошибку,
message: read ECONNRESET, stack: Error: read ECONNRESET
at exports._errnoException (util.js:1020:11)
at TCP.onread (net.js:568:26)
Настройка Redis: один сервер Redis в интрасети и 2 сервера Node js, каждый с 8 экземплярами PM2, работающими в DMZ. Существует межсетевой экран между серверами узлов и сервером Redis.
Версия NODE - версия 6.11.2 REDIS - версия 3.2.9 PM2 - 2.4.6
Мы также сделали дамп TCP. Дамп TCP показывает некоторые пакеты RST/ACK. TCP Dump
В nodeJS мы создаем одно соединение redis и пытаемся использовать одно соединение redis для всех запросов.
const Redis = require('redis');
const Config = require('../../config');
const Logger = require('../helpers/logger');
const redisClient = (function() {
// Start with a fake client so that we have a client that works
// even when Redis server is down
let client = {
get: function(key, callback) {
callback(null, null);
},
setex: function(key, time, value) {
Logger.info('Value:',value);
// Do nothing in particular
}
};
// Attempt to create a new instance of an actual redis client
const redisConfig = Config.get('/redis');
const tempClient = Redis.createClient(redisConfig.port,redisConfig.host, {
//eslint-disable-next-line
// console.log('[redis]','Creating the retry strategy');
retry_strategy: function(options) { //eslint-disable-line
//eslint-disable-next-line
console.log('[redis]','Creating the retry strategy');
if (options.error && options.error.code === 'ECONNREFUSED') {
// End reconnecting on a specific error and flush all commands with
// a individual error
//eslint-disable-next-line
console.log('[redis,error]','Connection refused error');
return new Error('The server refused the connection');
}
if (options.error && options.error.code === 'NR_CLOSED') {
//eslint-disable-next-line
console.log('[redis,error]','Connection closed error');
return new Error('The server closed the connection');
}
if (options.attempt > 5) {
// End reconnecting with built in error
//eslint-disable-next-line
console.log('Exceeded attempts');
return undefined;
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
//eslint-disable-next-line
console.log('Retrial time:' + options.total_retry_time);
return 1000;
}
// reconnect after
return Math.min(options.attempt * 100, 3000);
}
});
// Set the "client" variable to the actual redis client instance
// once a connection is established with the Redis server
tempClient.on('ready', () => {
client = tempClient;
});
tempClient.on('error', (error) => {
Logger.info(['redis','error'],'Redis client error:', error);
if (error.code === 'NR_CLOSED') {
tempClient.end();
client = Redis.createClient(redisConfig.port,redisConfig.host, {
retry_strategy: function(options) { //eslint-disable-line
if (options.error && options.error.code === 'NR_CLOSED') {
Logger.info(['redis','error'],'Connection closed error');
return new Error('The server refused the connection');
}
}
});
}
});
/**
* Get a redis client
* @return {Object} client - eventually a proper redis client object
* (if redis is up) or a fake client object (if redis is down)
*/
const getClient = function() {
Logger.info('Getting the client ' + client);
return client;
};
return {
getClient: getClient
};
}());
module.exports = redisClient;
Мы хотели бы знать, что именно вызывает проблемы с подключением и почему и каково решение.
2 ответа
в файле /etc/redis/redis.conf,
Заменить bind 127.0.0.1 на bind 0.0.0.0 Заменить защищенный режим да на защищенный режим нет
а затем Разрешите порт 6379, используя ufw allow 6379 и ufw allow 6379 / tcp
iptables -A INPUT -p tcp --dport 6379 -j ACCEPTiptables -A INPUT -p udp --dport 6379 -j ACCEPT
наконец-то
sudo systemctl stop redis sudo systemctl start redis
У меня была такая же проблема с облачными функциями Google Firebase. Проблема заключалась в том, что последняя версия Redis поддерживает связь вечно. Если процесс, который вызывает Redis, заканчивается вскоре после того, как он вызывает Redis, как в нашем случае с облачными функциями, вы должны установить timeout
установка чего-то отличного от значения по умолчанию 0.
Вы можете сделать это, изменив значение таймаута в файле конфигурации Redis с именем redis.conf
В документации сказано, что вы также можете установить время ожидания без перезапуска экземпляра, что невозможно, если ваш экземпляр Redis защищен и, следовательно, не может запустить что-то вроде CONFIG SET timeout 15
через Redis-Cli, как вы получите следующую ошибку:
(ошибка) ERR неизвестная команда
CONFIG