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.
@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:
tcp-keepalive 0
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"
Comentários muito úteis
Ok, finalmente capaz de reproduzir de forma confiável. Existem alguns requisitos:
tcp-keepalive 0
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.