421 Stimmen

Wie behebe ich den Fehler ECONNRESET in Node.js?

Ich betreibe eine Express.js-Anwendung, die Socket.io für eine Chat-Webanwendung verwendet, und ich erhalte den folgenden Fehler sporadisch etwa 5 Mal innerhalb von 24 Stunden. Der Node-Prozess ist in forever eingebunden und startet sich sofort neu.

Das Problem ist, dass das Neustarten von Express meine Benutzer aus ihren Räumen wirft und das möchte niemand.

Der Webserver wird von HAProxy proxied. Es gibt keine Probleme mit der Socket-Stabilität, es werden nur Websockets und Flashsockets-Transports verwendet. Ich kann diesen Fehler nicht absichtlich reproduzieren.

Das ist der Fehler mit Node v0.10.11:

    events.js:72
            throw er; // Unhandled 'error' event
                  ^
    Error: read ECONNRESET     //alternatively it s a 'write'
        at errnoException (net.js:900:11)
        at TCP.onread (net.js:555:19)
    error: Forever detected script exited with code: 8
    error: Forever restarting script for 2 time

EDIT (2013-07-22)

Habe sowohl den Fehlerhandler für den socket.io-Client als auch den unerfassten Ausnahme-Handler hinzugefügt. Es scheint, dass dieser den Fehler erfasst:

    process.on('uncaughtException', function (err) {
      console.error(err.stack);
      console.log("Node NICHT beenden...");
    });

Ich vermute also, dass es kein Socket.io-Problem ist, sondern eine HTTP-Anfrage an einen anderen Server, die ich mache, oder eine MySQL/Redis-Verbindung. Das Problem ist, dass der Fehler-Stack mir nicht hilft, meinen Codefehler zu identifizieren. Hier ist die Protokollausgabe:

    Error: read ECONNRESET
        at errnoException (net.js:900:11)
        at TCP.onread (net.js:555:19)

Wie kann ich herausfinden, was das verursacht? Wie bekomme ich mehr Informationen aus dem Fehler?

Okay, nicht sehr ausführlich, aber hier ist der Stacktrace mit Longjohn:

    Exception caught: Error ECONNRESET
    { [Error: read ECONNRESET]
      code: 'ECONNRESET',
      errno: 'ECONNRESET',
      syscall: 'read',
      __cached_trace__:
       [ { receiver: [Object],
           fun: [Function: errnoException],
           pos: 22930 },
         { receiver: [Object], fun: [Function: onread], pos: 14545 },
         {},
         { receiver: [Object],
           fun: [Function: fireErrorCallbacks],
           pos: 11672 },
         { receiver: [Object], fun: [Function], pos: 12329 },
         { receiver: [Object], fun: [Function: onread], pos: 14536 } ],
      __previous__:
       { [Error]
         id: 1061835,
         location: 'fireErrorCallbacks (net.js:439)',
         __location__: 'process.nextTick',
         __previous__: null,
         __trace_count__: 1,
         __cached_trace__: [ [Object], [Object], [Object] ] } }

Hier bediene ich die Flash-Socket-Richtliniendatei:

    net = require("net")
    net.createServer( (socket) =>
      socket.write("\n")
      socket.write("\n")
      socket.write("\n")
      socket.write("\n")
      socket.write("\n")
      socket.end()
    ).listen(843)

Kann das die Ursache sein?

16voto

Ashish Kaila Punkte 437

Ich hatte mit dem gleichen Problem zu kämpfen, aber ich habe es gemildert, indem ich Folgendes platziert habe:

server.timeout = 0;

vor server.listen. server ist hier ein HTTP-Server. Die Standard-Timeout-Zeit beträgt 2 Minuten gemäß der API-Dokumentation.

12voto

Joachim Isaksson Punkte 170533

Ja, Ihr Bereitstellen der Richtliniendatei kann definitiv den Absturz verursachen.

Zum Wiederholen fügen Sie einfach eine Verzögerung zu Ihrem Code hinzu:

net.createServer( function(socket) 
{
    for (i=0; i<1000000000; i++) ;
    socket.write("?xml version=\"1.0\"?>\n");
…

... und verwenden Sie telnet zum Verbinden mit dem Port. Wenn Sie telnet trennen, bevor die Verzögerung abgelaufen ist, erhalten Sie einen Absturz (unerwartete Ausnahme), wenn socket.write einen Fehler wirft.

Um den Absturz hier zu vermeiden, fügen Sie einfach einen Fehlerbehandlung vor dem Lesen/Schreiben des Sockets hinzu:

net.createServer(function(socket)
{
    for(i=0; i<1000000000; i++);
    socket.on('error', function(error) { console.error("Fehler", error); });
    socket.write("?xml version=\"1.0\"?>\n");
}

Bei dem oben beschriebenen Trennversuch erhalten Sie nur eine Protokollmeldung anstelle eines Absturzes.

Und wenn Sie fertig sind, denken Sie daran, die Verzögerung zu entfernen.

11voto

happy_marmoset Punkte 2032

Ein weiterer möglicher Fall (aber selten) könnte sein, wenn Sie serverseitige Kommunikationen haben und server.maxConnections auf einen sehr niedrigen Wert gesetzt haben.

In nodes Kernbibliothek net.js wird clientHandle.close() aufgerufen, was auch den Fehler ECONNRESET verursacht:

if (self.maxConnections && self._connections >= self.maxConnections) {
  clientHandle.close(); // verursacht ECONNRESET am anderen Ende
  return;
}

9voto

Elson D'Sa Punkte 99

ECONNRESET tritt auf, wenn die Serverseite die TCP-Verbindung schließt und Ihre Anfrage an den Server nicht erfüllt wird. Der Server antwortet mit der Nachricht, dass die Verbindung, auf die Sie sich beziehen, eine ungültige Verbindung ist.

Warum sendet der Server eine Anfrage mit ungültiger Verbindung?

Angenommen, Sie haben eine Keep-Alive-Verbindung zwischen Client und Server aktiviert. Das Keep-Alive-Timeout ist auf 15 Sekunden konfiguriert. Das bedeutet, dass, wenn Keep-Alive 15 Sekunden lang inaktiv ist, eine Verbindungsabbrufanfrage gesendet wird. Nach 15 Sekunden fordert der Server den Client auf, die Verbindung zu schließen. ABER, wenn der Server diese Anfrage sendet, sendet der Client eine neue Anfrage, die bereits auf dem Weg zum Server ist. Da diese Verbindung jetzt ungültig ist, wird der Server die Anfrage mit dem Fehler ECONNRESET ablehnen. Das Problem tritt also aufgrund weniger Anfragen an das Serverende auf. Bitte deaktivieren Sie also das Keep-Alive und es wird einwandfrei funktionieren.

8voto

Waog Punkte 6959

Ich hatte auch diesen Fehler und konnte ihn nach tagelangem Debuggen und Analysieren lösen:

meine Lösung

Für mich war VirtualBox (für Docker) das Problem. Ich hatte Portweiterleitung auf meiner VM konfiguriert und der Fehler trat nur an dem weitergeleiteten Port auf.

allgemeine Schlussfolgerungen

Die folgenden Beobachtungen können Ihnen Tage Arbeit ersparen, die ich investieren musste:

  • Für mich trat das Problem nur bei Verbindungen von localhost zu localhost an einem Port auf. -> Überprüfen Sie, ob sich die Probleme ändern, wenn Sie eine dieser Konstanten ändern.
  • Für mich trat das Problem nur auf meinem Rechner auf -> lassen Sie es jemand anderen probieren.
  • Für mich trat das Problem nur nach einer Weile auf und konnte nicht zuverlässig reproduziert werden.
  • Mein Problem konnte mit keinen der Nodes oder Express (Debug-)Tools inspiziert werden. -> Verschwenden Sie keine Zeit damit.

-> Finden Sie heraus, ob etwas mit Ihrem Netzwerk (-einstellungen) herumspielt, wie VMs, Firewalls usw. Dies ist wahrscheinlich die Ursache des Problems.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X