Node-redis: As assinaturas não recebem dados após a reconexão

Criado em 5 jul. 2017  ·  6Comentários  ·  Fonte: NodeRedis/node-redis

node_redis : 2.7.1
redis : 3.2
plataforma : Amazon linux
descrição:
Quando ocorre o instantâneo do redis, ele desconecta o cliente do redis. O cliente se reconecta e se inscreve novamente, no entanto, ele não recebe mais dados. Isso pode ser reproduzido emitindo um comando SAVE por meio do 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');

Histórico

Conexão inicial

info: Connected to Redis
info: subscription_set:
info: Subscribed to:  test 1

Emitir um comando SAVE no 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

É neste ponto que o cliente não receberá mais nenhum dado publicado para o teste de canal. Se você tiver alguma dúvida ou precisar de mais informações para reproduzir, por favor me avise.

bug

Comentários muito úteis

Ok, finalmente capaz de reproduzir de forma confiável. Existem alguns requisitos:

  • redis 3.2.0 - DEVE definir tcp-keepalive 0
  • configurar um canal
  • configurar o script do nó para se conectar e se inscrever no canal
  • espere 2 horas e 1 minuto

O que você verá é que a cada 2 horas (pelo menos para mim) é um erro ECONNRESET. Neste ponto, o soquete parece ainda estar aberto no redis, mas talvez o processo do nó tenha perdido uma referência a ele e aberto um novo soquete. Durante a noite, eu tinha como 1 cliente conectado por bloco de 2 horas mais o processo atualmente em execução ao emitir CLIENT LIST do redis-cli.

É importante observar que todos os clientes se reconectaram com êxito, mas não receberam dados. Tenho um palpite de que os dados estavam sendo enviados, mas para a conexão antiga não para a nova ... mas isso é totalmente um palpite.

Agora, eu não tenho 100% de certeza se este é um bug do node_redis ou realmente um bug do node, então se este for o lugar errado para o arquivo, me avise. Eu ficaria feliz em tentar depurar / avançar, mas tenho tempo limitado.

A correção foi definir tcp-keepalive 300 que mantém a conexão ativa ... mas isso parece complicado, pois o cliente deve ser capaz de se reconectar com sucesso.

Todos 6 comentários

@BridgeAR @iamjem Pode estar relacionado com # 1249

Obrigado pela descrição detalhada, no entanto, ainda não consegui reproduzi-la. Quando eu emito SAVE através do redis-cli, a conexão não é reiniciada.

Quando eu paro manualmente o servidor redis e o inicio novamente, ele parece receber mensagens bem.

Tenho testado no Mac, vou tentar reproduzi-lo também no Linux

Hmmm ... isso é interessante. Estava ocorrendo com uma instalação de redis totalmente stock construída a partir da fonte. A única opção que mudei foi permitir conexões remotas. Vou dar uma olhada em breve e ver se consigo descobrir o que está acontecendo. @jdegger

@jdegger Não consigo reproduzir localmente, apenas na AWS em condições superespecíficas. Posso criar uma segunda cópia deste AMI e fornecer um código que permitirá a sua reprodução, mas aparentemente é algo específico para execução no AWS. Avise-me se estiver interessado ... caso contrário, diria que prossiga e feche o problema

Ok, finalmente capaz de reproduzir de forma confiável. Existem alguns requisitos:

  • redis 3.2.0 - DEVE definir tcp-keepalive 0
  • configurar um canal
  • configurar o script do nó para se conectar e se inscrever no canal
  • espere 2 horas e 1 minuto

O que você verá é que a cada 2 horas (pelo menos para mim) é um erro ECONNRESET. Neste ponto, o soquete parece ainda estar aberto no redis, mas talvez o processo do nó tenha perdido uma referência a ele e aberto um novo soquete. Durante a noite, eu tinha como 1 cliente conectado por bloco de 2 horas mais o processo atualmente em execução ao emitir CLIENT LIST do redis-cli.

É importante observar que todos os clientes se reconectaram com êxito, mas não receberam dados. Tenho um palpite de que os dados estavam sendo enviados, mas para a conexão antiga não para a nova ... mas isso é totalmente um palpite.

Agora, eu não tenho 100% de certeza se este é um bug do node_redis ou realmente um bug do node, então se este for o lugar errado para o arquivo, me avise. Eu ficaria feliz em tentar depurar / avançar, mas tenho tempo limitado.

A correção foi definir tcp-keepalive 300 que mantém a conexão ativa ... mas isso parece complicado, pois o cliente deve ser capaz de se reconectar com sucesso.

@shmendo

Nosso também mostra que o erro ECONNRESET acontece a cada 2 horas. Mas eu verifiquei tcp-keepalive, é 300

CONFIG GET tcp-keepalive
1) "tcp-keepalive"
2) "300"
Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

Mickael-van-der-Beek picture Mickael-van-der-Beek  ·  6Comentários

twappworld picture twappworld  ·  7Comentários

jackycchen picture jackycchen  ·  4Comentários

betimer picture betimer  ·  5Comentários

aletorrado picture aletorrado  ·  6Comentários