it-swarm.com.de

Knoten js ECONNRESET

Ich betreibe eine Express-js-Anwendung mit socket.io für einen Chat webapp und ich bekomme etwa fünfmal während .__ den folgenden Fehler zufällig. 24h Der Node-Prozess ist für immer eingeschlossen und startet neu sich sofort.

Das Problem ist, dass ein Neustart von Express meine Benutzer aus ihren Räumen führt und das will niemand.

Der Webserver wird über HAProxy weitergeleitet. Es gibt keine Probleme mit der Sockelstabilität, nur mit Websockets und Flashsockets-Transporten. Ich kann das absichtlich nicht reproduzieren. 

Dies ist der Fehler mit dem Knoten 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)

Der Client-Handler von socket.io und der nicht erfasste Exception-Handler wurden hinzugefügt. Scheint, dass dieser den Fehler abfängt:

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

Ich vermute also, dass es sich nicht um ein socket.io-Problem handelt, sondern um eine http-Anfrage an einen anderen Server oder eine mysql/redis-Verbindung. Das Problem ist, dass der Fehlerstapel mir nicht hilft, mein Codeproblem zu identifizieren. Hier ist die Protokollausgabe: 

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

Woher weiß ich, was das verursacht? Wie bekomme ich mehr aus dem Fehler? 

Ok, 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("<?xml version=\"1.0\"?>\n")
  socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n")
  socket.write("<cross-domain-policy>\n")
  socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n")
  socket.write("</cross-domain-policy>\n")
  socket.end()
).listen(843)

Kann das die Ursache sein? 

223
Samson

Dies wurde durch einen einfachen TCP-Server verursacht, den ich zum Bereitstellen der Flash-Richtliniendatei hatte. Ich kann den Fehler jetzt mit einem Handler abfangen:

# serving the flash policy file
net = require("net")

net.createServer((socket) =>
  //just added
  socket.on("error", (err) =>
    console.log("Caught flash policy server socket error: ")
    console.log(err.stack)
  )

  socket.write("<?xml version=\"1.0\"?>\n")
  socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n")
  socket.write("<cross-domain-policy>\n")
  socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n")
  socket.write("</cross-domain-policy>\n")
  socket.end()
).listen(843)
31
Samson

Sie haben es vielleicht schon erraten: Es ist ein Verbindungsfehler. 

"ECONNRESET" bedeutet, dass die andere Seite der TCP - Konversation abrupt das Ende der Verbindung geschlossen hat. Dies ist höchstwahrscheinlich auf einen oder mehrere Anwendungsprotokollfehler zurückzuführen. Sie können sich die API-Serverprotokolle ansehen, um zu sehen, ob sich etwas darüber beschwert.

Da Sie jedoch auch nach einer Möglichkeit suchen, den Fehler zu überprüfen und möglicherweise das Problem zu debuggen, sollten Sie einen Blick auf " Debuggen eines Socket-Auflegers in NodeJS? "werfen Bei stackoverflow in Bezug auf eine ähnliche Frage gepostet.

Schnelle und schmutzige Lösung für die Entwicklung:

Verwenden Sie longjohn , um lange Stapelspuren zu erhalten, die die asynchronen Operationen enthalten.

Saubere und korrekte Lösung: Technisch gesehen, im Knoten, wenn Sie ein 'error'-Ereignis ausgeben und niemand darauf hört, wird ausgegeben. Damit es nicht geworfen wird, legen Sie einen Hörer darauf und handhaben Sie es selbst. Auf diese Weise können Sie den Fehler mit weiteren Informationen protokollieren.

Um einen Listener für eine Anrufgruppe zu haben, können Sie domains verwenden und andere Fehler während der Laufzeit abfangen. Stellen Sie sicher, dass sich jeder async-Vorgang, der sich auf http (Server/Client) bezieht, im Vergleich zu den anderen Teilen des Codes in einem anderen domain - Kontext befindet. Die Domäne überwacht automatisch die error -Ereignisse und leitet sie an ihren eigenen Handler weiter. Sie hören also nur diesen Handler und erhalten die Fehlerdaten. Sie erhalten auch kostenlos weitere Informationen.

EDIT (2013-07-22)

Wie ich oben schrieb: 

"ECONNRESET" bedeutet, dass die andere Seite der TCP - Konversation abrupt das Ende der Verbindung geschlossen hat. Dies ist höchstwahrscheinlich auf einen oder mehrere Anwendungsprotokollfehler zurückzuführen. Sie können sich die API-Serverprotokolle ansehen, um zu sehen, ob sich etwas darüber beschwert.

Was könnte auch der Fall sein: Zu anderen Zeitpunkten ist die andere Seite überlastet und bricht dadurch die Verbindung ab. Wenn das der Fall ist, kommt es darauf an, mit was Sie sich genau verbinden ...

Eines ist jedoch sicher: Sie haben tatsächlich einen Lesefehler in Ihrer TCP -Verbindung, was die Ausnahme verursacht. Sie können dies sehen, indem Sie den Fehlercode anzeigen, den Sie in Ihrer Bearbeitung gepostet haben, um ihn zu bestätigen. 

209
e-sushi

Ich hatte ein ähnliches Problem, bei dem Apps nach einem Upgrade von Node fehlerhaft waren. Ich glaube, dass dies auf Node Release v0.9.10 zurückgeführt werden kann:

  • net: nicht unterdrücken ECONNRESET (Ben Noordhuis)

Frühere Versionen wurden bei Unterbrechungen vom Client nicht fehlerfrei ausgeführt. Eine Unterbrechung der Verbindung vom Client löst den Fehler ECONNRESET in Node aus. Ich glaube, das ist eine beabsichtigte Funktionalität für Node, daher lag der Fix (zumindest für mich) darin, den Fehler zu beheben, den Sie meiner Meinung nach in unCaught-Ausnahmen gemacht haben. Obwohl ich damit im net.socket-Handler zurecht komme.

Sie können das demonstrieren:

Erstellen Sie einen einfachen Socket-Server, und erhalten Sie Node v0.9.9 und v0.9.10.

require('net')
    .createServer( function(socket) 
    {
           // no nothing
    })
    .listen(21, function()
     {
           console.log('Socket ON')
    })

Starten Sie es mit v0.9.9 und versuchen Sie dann, zu diesem Server über FTP zu gelangen. Ich verwende FTP und Port 21 nur, weil ich unter Windows bin und einen FTP-Client habe, aber keinen Telnet-Client. 

Dann unterbrechen Sie einfach die Verbindung. (Ich mache gerade Ctrl-C)

Sie sollten NO ERROR sehen, wenn Sie Node v0.9.9 verwenden, und ERROR, wenn Sie Node v.0.9.10 und höher verwenden.

In der Produktion verwende ich v.0.10. etwas und es gibt immer noch den Fehler. Ich denke, dies ist beabsichtigt und die Lösung besteht darin, den Fehler in Ihrem Code zu behandeln.

24
John Williams

Ich war mit dem gleichen Problem konfrontiert, aber ich habe es gemindert:

server.timeout = 0;

vor server.listen. server ist hier ein HTTP-Server. Das Standard-Timeout beträgt laut der API-Dokumentation 2 Minuten.

14
Ashish Kaila

Hatte heute dasselbe Problem ... Nach einigen Nachforschungen fand ich eine sehr nützliche --abort-on-uncaught-exception node.js-Option . Es bietet nicht nur eine viel ausführlichere und nützlichere Fehler-Stack-Ablaufverfolgung, sondern spart auch die Kerndatei beim Absturz der Anwendung, wodurch weiteres Debugging möglich ist.

12
stainful

Ja, Ihre Bereitstellung der Richtliniendatei kann definitiv zum Absturz führen.

Um es zu 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, um eine Verbindung zum Port herzustellen. Wenn Sie Telnet trennen, bevor die Verzögerung abgelaufen ist, kommt es zu einem Absturz (nicht erfasste Ausnahme), wenn socket.write einen Fehler ausgibt.

Um den Absturz hier zu vermeiden, fügen Sie einfach einen Fehlerbehandler hinzu, bevor Sie den Socket lesen/schreiben:

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

Wenn Sie versuchen, die obige Verbindung zu trennen, wird statt eines Absturzes nur eine Protokollmeldung angezeigt.

Wenn Sie fertig sind, vergessen Sie nicht, die Verzögerung zu beseitigen.

7

Ein anderer möglicher Fall (wenn auch selten) könnte der Fall sein, wenn Sie eine Server-zu-Server-Kommunikation haben und server.maxConnections auf einen sehr niedrigen Wert setzen.

Im Knoten lib net.js des Knotens wird clientHandle.close() aufgerufen, was ebenfalls den Fehler ECONNRESET verursacht:

if (self.maxConnections && self._connections >= self.maxConnections) {
  clientHandle.close(); // causes ECONNRESET on the other end
  return;
}
5
happy_marmoset

Ich erhalte auch einen ECONNRESET-Fehler während meiner Entwicklung. Ich löse das Problem dadurch, dass not nodemon zum Starten meines Servers verwendet. Verwenden Sie einfach "node server.js", um meinen Server zu starten, um mein Problem zu beheben. 

Es ist seltsam, aber es hat für mich funktioniert, jetzt sehe ich den ECONNRESET-Fehler nie wieder.

2
Andrew Lam

Ich habe das Problem gelöst, indem ich einfach an ein anderes Netzwerk angeschlossen habe . Das ist eines der möglichen Probleme.

Wie oben erläutert, bedeutet ECONNRESET, dass die Konversation TCP das Ende der Verbindung abrupt geschlossen hat. 

Ihre Internetverbindung blockiert möglicherweise die Verbindung zu einigen Servern. In meinem Fall habe ich versucht, eine Verbindung zu mLab (Cloud-Datenbankdienst, der MongoDB-Datenbanken hostet) herzustellen. Und mein ISP blockiert es. 

1
Yousef

Ich hatte auch diesen Fehler und konnte ihn nach Tagen des Debugging und der Analyse beheben:

meine Lösung

Für mich war VirtualBox (für Docker) das Problem. Ich hatte Port-Forwarding auf meiner VM konfiguriert, und der Fehler trat nur beim weitergeleiteten Port auf.

allgemeine Schlussfolgerungen

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

  • Bei mir trat das Problem nur bei Verbindungen von localhost zu localhost an einem Port auf. -> Überprüfen Sie das Ändern einer dieser Konstanten, um das Problem zu lösen.
  • Bei mir ist das Problem nur auf meinem Rechner aufgetreten -> lassen Sie es von jemand anderem versuchen.
  • Bei mir trat das Problem erst nach einiger Zeit auf und konnte nicht zuverlässig reproduziert werden
  • Mein Problem konnte nicht mit Knoten oder Ausdrücken (Debug-) Werkzeugen untersucht werden. -> verschwenden Sie keine Zeit damit

-> Finden Sie heraus, ob etwas mit Ihrem Netzwerk (-Einstellungen), wie VMs, Firewalls usw., durcheinander geraten ist.

1
Waog

Ich hatte dieses Problem gelöst durch:

  • Schalten Sie meine WLAN-/Ethernet-Verbindung aus und wieder ein. 
  • Ich habe Folgendes eingegeben: npm update im Terminal, um npm zu aktualisieren.
  • Ich habe versucht, mich von der Sitzung abzumelden und mich erneut anzumelden

Danach habe ich den gleichen npm Befehl ausprobiert und das Gute war, dass es geklappt hat. Ich war mir nicht sicher, ob es so einfach ist.

Ich verwende CENTOS 7

0
muhammad tayyab

Versuchen Sie, diese Optionen zu socket.io hinzuzufügen:

const options = { transports: ['websocket'], pingTimeout: 3000, pingInterval: 5000 };

Ich hoffe, dies wird dir helfen !

0
sol404