node_redis : 2.7.1
Redis : 3.2
платформа : Amazon linux
описание:
Когда происходит моментальный снимок redis, он отключает клиент redis. Клиент повторно подключается и повторно подписывается, однако он больше не получает данные. Это можно воспроизвести, введя команду SAVE
через redis-cli.
JS
const redis = require('redis');
const redisClient = redis.createClient({
host: config.redisEndpoint,
port: config.redisPort,
});
redisClient.on('connect', () => {
console.log('Connected to Redis');
console.log('subscription_set:', redisClient.subscription_set);
});
redisClient.on('reconnecting', (stats) => {
console.log('Reconnecting to Redis', stats);
});
redisClient.on('error', (error) => {
console.log('Failed to connect to Redis: ', error);
});
redisClient.on('subscribe', (channel, count) => { // eslint-disable-line no-unused-vars
console.log('Subscribed to: ', channel, count);
});
redisClient.on('message', (channel, message) => { // eslint-disable-line no-unused-vars
console.log('Received from: ', channel, message);
});
redisClient.subscribe('test');
Журналы
Первоначальное подключение
info: Connected to Redis
info: subscription_set:
info: Subscribed to: test 1
Выполнение команды SAVE в redis-cli
info: Error: Redis connection to 34.213.3.19:6379 failed - read ECONNRESET
info: Reconnecting to Redis delay=983, attempt=4, code=ECONNRESET, errno=ECONNRESET, syscall=connect, address=127.0.0.1, port=6379, total_retry_time=1118, times_connected=1
info: Connected to Redis
info: subscription_set: subscribe_test=test
info: Subscribed to: test 1
Именно в этот момент клиент больше не будет получать никаких данных, опубликованных для тестирования канала. Если у вас есть вопросы или вам нужна дополнительная информация для воспроизведения, дайте мне знать.
@BridgeAR @iamjem Может быть связано с # 1249
Спасибо за подробное описание, но мне пока не удалось его воспроизвести. Когда я выдаю SAVE
через redis-cli, соединение не сбрасывается.
Когда я вручную останавливаю сервер Redis и запускаю его снова, кажется, что сообщения принимаются нормально.
Я тестировал это на Mac, постараюсь воспроизвести и на Linux.
Хммм ... это интересно. Это происходило с полностью стандартной установкой Redis, построенной из исходного кода. Единственный вариант, который я изменил, - разрешить удаленные подключения. Я посмотрю в ближайшее время и посмотрю, смогу ли я понять, что случилось. @jdegger
@jdegger Я не могу воспроизводить локально, только в AWS при особых условиях. Я могу создать вторую копию этого AMI и предоставить код, который позволит вам воспроизвести, но, похоже, это что-то особенное для работы в AWS. Дайте мне знать, если вам интересно ... в противном случае я бы сказал, продолжайте и закройте проблему
Хорошо, наконец-то удалось надежно воспроизвести. Есть несколько требований:
tcp-keepalive 0
Вы увидите, что каждые 2 часа (по крайней мере, для меня) возникает ошибка ECONNRESET. На этом этапе сокет, похоже, все еще открыт в Redis, но, возможно, процесс узла потерял ссылку на него и открыл новый сокет? За ночь у меня был примерно 1 клиент, подключенный за 2-часовой блок, плюс текущий процесс при выдаче CLIENT LIST
из redis-cli.
Важно отметить, что все клиенты успешно повторно подключались, но не получали данные. У меня есть подозрение, что данные выталкиваются, но к старому соединению, а не к новому ... но это совершенно догадка.
Я не уверен на 100%, является ли это ошибкой node_redis или на самом деле ошибкой с node, поэтому, если это неправильное место для файла, просто дайте мне знать. Я был бы счастлив попробовать отладить / пройти через, но у меня ограниченное время.
Исправление заключалось в установке tcp-keepalive 300
которая поддерживает соединение в активном состоянии ... но это кажется неудобным, поскольку клиент должен иметь возможность успешно повторно подключиться.
@shmendo
Наш также показывает, что ошибка ECONNRESET происходит каждые 2 часа. Но проверял tcp-keepalive, 300
CONFIG GET tcp-keepalive
1) "tcp-keepalive"
2) "300"
Самый полезный комментарий
Хорошо, наконец-то удалось надежно воспроизвести. Есть несколько требований:
tcp-keepalive 0
Вы увидите, что каждые 2 часа (по крайней мере, для меня) возникает ошибка ECONNRESET. На этом этапе сокет, похоже, все еще открыт в Redis, но, возможно, процесс узла потерял ссылку на него и открыл новый сокет? За ночь у меня был примерно 1 клиент, подключенный за 2-часовой блок, плюс текущий процесс при выдаче
CLIENT LIST
из redis-cli.Важно отметить, что все клиенты успешно повторно подключались, но не получали данные. У меня есть подозрение, что данные выталкиваются, но к старому соединению, а не к новому ... но это совершенно догадка.
Я не уверен на 100%, является ли это ошибкой node_redis или на самом деле ошибкой с node, поэтому, если это неправильное место для файла, просто дайте мне знать. Я был бы счастлив попробовать отладить / пройти через, но у меня ограниченное время.
Исправление заключалось в установке
tcp-keepalive 300
которая поддерживает соединение в активном состоянии ... но это кажется неудобным, поскольку клиент должен иметь возможность успешно повторно подключиться.