Node-redis: Подписки не получают данные после повторного подключения

Созданный на 5 июл. 2017  ·  6Комментарии  ·  Источник: NodeRedis/node-redis

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

Именно в этот момент клиент больше не будет получать никаких данных, опубликованных для тестирования канала. Если у вас есть вопросы или вам нужна дополнительная информация для воспроизведения, дайте мне знать.

Самый полезный комментарий

Хорошо, наконец-то удалось надежно воспроизвести. Есть несколько требований:

  • redis 3.2.0 - ДОЛЖЕН установить tcp-keepalive 0
  • настроить канал
  • настроить скрипт узла для подключения и подписаться на канал
  • подождите 2 часа и 1 минуту

Вы увидите, что каждые 2 часа (по крайней мере, для меня) возникает ошибка ECONNRESET. На этом этапе сокет, похоже, все еще открыт в Redis, но, возможно, процесс узла потерял ссылку на него и открыл новый сокет? За ночь у меня был примерно 1 клиент, подключенный за 2-часовой блок, плюс текущий процесс при выдаче CLIENT LIST из redis-cli.

Важно отметить, что все клиенты успешно повторно подключались, но не получали данные. У меня есть подозрение, что данные выталкиваются, но к старому соединению, а не к новому ... но это совершенно догадка.

Я не уверен на 100%, является ли это ошибкой node_redis или на самом деле ошибкой с node, поэтому, если это неправильное место для файла, просто дайте мне знать. Я был бы счастлив попробовать отладить / пройти через, но у меня ограниченное время.

Исправление заключалось в установке tcp-keepalive 300 которая поддерживает соединение в активном состоянии ... но это кажется неудобным, поскольку клиент должен иметь возможность успешно повторно подключиться.

Все 6 Комментарий

@BridgeAR @iamjem Может быть связано с # 1249

Спасибо за подробное описание, но мне пока не удалось его воспроизвести. Когда я выдаю SAVE через redis-cli, соединение не сбрасывается.

Когда я вручную останавливаю сервер Redis и запускаю его снова, кажется, что сообщения принимаются нормально.

Я тестировал это на Mac, постараюсь воспроизвести и на Linux.

Хммм ... это интересно. Это происходило с полностью стандартной установкой Redis, построенной из исходного кода. Единственный вариант, который я изменил, - разрешить удаленные подключения. Я посмотрю в ближайшее время и посмотрю, смогу ли я понять, что случилось. @jdegger

@jdegger Я не могу воспроизводить локально, только в AWS при особых условиях. Я могу создать вторую копию этого AMI и предоставить код, который позволит вам воспроизвести, но, похоже, это что-то особенное для работы в AWS. Дайте мне знать, если вам интересно ... в противном случае я бы сказал, продолжайте и закройте проблему

Хорошо, наконец-то удалось надежно воспроизвести. Есть несколько требований:

  • redis 3.2.0 - ДОЛЖЕН установить tcp-keepalive 0
  • настроить канал
  • настроить скрипт узла для подключения и подписаться на канал
  • подождите 2 часа и 1 минуту

Вы увидите, что каждые 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"
Была ли эта страница полезной?
0 / 5 - 0 рейтинги