Node-redis: Abonnements erhalten nach dem erneuten Verbinden keine Daten

Erstellt am 5. Juli 2017  ·  6Kommentare  ·  Quelle: NodeRedis/node-redis

node_redis : 2.7.1
Redis : 3.2
Plattform : Amazon Linux
Beschreibung:
Wenn das Snapshotting von Redis auftritt, wird der Redis-Client getrennt. Der Client stellt die Verbindung wieder her und meldet sich erneut an. Er empfängt jedoch keine Daten mehr. Dies kann reproduziert werden, indem ein Befehl SAVE über redis-cli ausgegeben wird.

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');

Protokolle

Erstverbindung

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

Ausgabe eines SAVE-Befehls in 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

Zu diesem Zeitpunkt erhält der Client keine Daten mehr, die für den Kanaltest veröffentlicht wurden. Wenn Sie Fragen haben oder weitere Informationen zur Reproduktion benötigen, lassen Sie es mich bitte wissen.

bug

Hilfreichster Kommentar

Ok, endlich in der Lage, zuverlässig zu reproduzieren. Es gibt einige Anforderungen:

  • redis 3.2.0 - MUSS tcp-keepalive 0
  • Richten Sie einen Kanal ein
  • Konfigurieren Sie das Knotenskript für die Verbindung und abonnieren Sie den Kanal
  • Warten Sie 2 Stunden und 1 Minute

Sie werden sehen, dass alle 2 Stunden (zumindest für mich) ein ECONNRESET-Fehler vorliegt. Zu diesem Zeitpunkt scheint der Socket in Redis noch offen zu sein, aber möglicherweise hat der Knotenprozess einen Verweis darauf verloren und einen neuen Socket geöffnet? Über Nacht hatte ich gerne 1 Client pro 2-Stunden-Block plus den aktuell laufenden Prozess verbunden, als CLIENT LIST von redis-cli ausgegeben wurde.

Es ist wichtig zu beachten, dass die Clients alle erfolgreich die Verbindung wiederhergestellt haben, aber keine Daten empfangen haben. Ich habe eine Vermutung, dass die Daten herausgeschoben wurden, aber auf die alte Verbindung nicht die neue ... aber das ist total eine Vermutung.

Jetzt bin ich mir nicht 100% sicher, ob dies ein node_redis-Fehler oder tatsächlich ein Fehler mit node ist. Wenn dies also der falsche Ort zum Ablegen ist, lassen Sie es mich einfach wissen. Ich würde gerne versuchen, zu debuggen / durchzugehen, habe aber nur begrenzte Zeit.

Das Update bestand darin, tcp-keepalive 300 festzulegen, wodurch die Verbindung aktiv bleibt ... aber dies fühlt sich wackelig an, da der Client in der Lage sein sollte, die Verbindung erfolgreich wiederherzustellen.

Alle 6 Kommentare

@BridgeAR @iamjem Könnte mit # 1249 verwandt sein

Vielen Dank für Ihre detaillierte Beschreibung, die ich jedoch noch nicht reproduzieren konnte. Wenn ich über redis-cli ein SAVE ausstelle, wird die Verbindung nicht zurückgesetzt.

Wenn ich den Redis-Server manuell stoppe und erneut starte, scheint er Nachrichten in Ordnung zu empfangen.

Ich habe dies auf einem Mac getestet und werde versuchen, es auch unter Linux zu reproduzieren

Hmmm ... das ist interessant. Dies geschah mit einer vollständig auf Lager befindlichen Redis-Installation, die aus dem Quellcode erstellt wurde. Die einzige Option, die ich geändert habe, war, Remoteverbindungen zuzulassen. Ich werde in Kürze einen Blick darauf werfen und sehen, ob ich herausfinden kann, was los ist. @jdegger

@jdegger Ich kann nicht lokal

Ok, endlich in der Lage, zuverlässig zu reproduzieren. Es gibt einige Anforderungen:

  • redis 3.2.0 - MUSS tcp-keepalive 0
  • Richten Sie einen Kanal ein
  • Konfigurieren Sie das Knotenskript für die Verbindung und abonnieren Sie den Kanal
  • Warten Sie 2 Stunden und 1 Minute

Sie werden sehen, dass alle 2 Stunden (zumindest für mich) ein ECONNRESET-Fehler vorliegt. Zu diesem Zeitpunkt scheint der Socket in Redis noch offen zu sein, aber möglicherweise hat der Knotenprozess einen Verweis darauf verloren und einen neuen Socket geöffnet? Über Nacht hatte ich gerne 1 Client pro 2-Stunden-Block plus den aktuell laufenden Prozess verbunden, als CLIENT LIST von redis-cli ausgegeben wurde.

Es ist wichtig zu beachten, dass die Clients alle erfolgreich die Verbindung wiederhergestellt haben, aber keine Daten empfangen haben. Ich habe eine Vermutung, dass die Daten herausgeschoben wurden, aber auf die alte Verbindung nicht die neue ... aber das ist total eine Vermutung.

Jetzt bin ich mir nicht 100% sicher, ob dies ein node_redis-Fehler oder tatsächlich ein Fehler mit node ist. Wenn dies also der falsche Ort zum Ablegen ist, lassen Sie es mich einfach wissen. Ich würde gerne versuchen, zu debuggen / durchzugehen, habe aber nur begrenzte Zeit.

Das Update bestand darin, tcp-keepalive 300 festzulegen, wodurch die Verbindung aktiv bleibt ... aber dies fühlt sich wackelig an, da der Client in der Lage sein sollte, die Verbindung erfolgreich wiederherzustellen.

@shmendo

Unser zeigt auch, dass der ECONNRESET-Fehler alle 2 Stunden auftritt. Aber ich habe tcp-keepalive überprüft, es ist 300

CONFIG GET tcp-keepalive
1) "tcp-keepalive"
2) "300"
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen