Ich führe eine Express.js-Anwendung mit Socket.io für eine Chat-Webanwendung aus und erhalte den folgenden Fehler ungefähr fünfmal während 24 Stunden zufällig. Der Knotenprozess ist für immer eingebunden und startet sich sofort neu.
Das Problem ist, dass ein Neustart von Express meine Benutzer aus ihren Räumen wirft und niemand das will.
Der Webserver wird von HAProxy vertreten. Es gibt keine Probleme mit der Socket-Stabilität, nur die Verwendung von Websockets und Flashsockets-Transporten. Ich kann das nicht absichtlich reproduzieren.
Dies ist der Fehler bei 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
BEARBEITEN (22.07.2013)
Sowohl der Socket.io-Client-Fehlerbehandler als auch der nicht erfasste Ausnahmebehandler wurden hinzugefügt. Scheint, dass dieser den Fehler fä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 kann ich mehr aus dem Fehler herausholen?
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 diene ich der 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?
Antworten:
Sie haben es vielleicht schon erraten: Es ist ein Verbindungsfehler.
"ECONNRESET" bedeutet, dass die andere Seite der TCP-Konversation das Ende der Verbindung abrupt geschlossen hat. Dies ist höchstwahrscheinlich auf einen oder mehrere Anwendungsprotokollfehler zurückzuführen. Sie können in den API-Serverprotokollen nachsehen, ob sich etwas beschwert.
Da Sie aber auch nach einer Möglichkeit suchen, den Fehler zu überprüfen und das Problem möglicherweise zu debuggen, sollten Sie sich " So debuggen Sie einen Socket-Aufhängefehler in NodeJS? " Anschauen, der bei stackoverflow in Bezug auf eine ähnliche Frage veröffentlicht wurde.
BEARBEITEN (22.07.2013)
Wie ich oben geschrieben habe:
Was auch der Fall sein könnte: Zu zufälligen Zeiten ist die andere Seite überlastet und unterbricht dadurch einfach die Verbindung. Wenn dies der Fall ist, hängt es davon ab, mit was Sie sich genau verbinden ...
Eines ist jedoch sicher: Sie haben tatsächlich einen Lesefehler in Ihrer TCP-Verbindung, der die Ausnahme verursacht. Sie können dies sehen, indem Sie sich den Fehlercode ansehen, den Sie in Ihrer Bearbeitung gepostet haben, der dies bestätigt.
quelle
Ein einfacher TCP-Server, den ich zum Bereitstellen der Flash-Richtliniendatei hatte, verursachte dies. Ich kann den Fehler jetzt mit einem Handler abfangen:
quelle
socket.destroy()
den Fehlerbehandler aufgerufen , um sicherzugehen. Leider kann ich keine Dokumentation finden, ob dies erforderlich ist, aber es wird kein Fehler ausgegeben.Ich hatte ein ähnliches Problem, bei dem Apps nach einem Upgrade von Node fehlerhaft wurden. Ich glaube, dass dies auf Node Release v0.9.10 dieses Artikels zurückgeführt werden kann:
Frühere Versionen würden bei Unterbrechungen durch den Client keine Fehler verursachen. Eine Unterbrechung der Verbindung vom Client löst den Fehler ECONNRESET im Knoten aus. Ich glaube, dies ist eine beabsichtigte Funktionalität für Node, daher bestand die Lösung (zumindest für mich) darin, den Fehler zu behandeln, den Sie meiner Meinung nach in nicht erfassten Ausnahmen getan haben. Obwohl ich es im net.socket-Handler erledige.
Sie können dies demonstrieren:
Erstellen Sie einen einfachen Socket-Server und holen Sie sich Node v0.9.9 und v0.9.10.
Starten Sie es mit v0.9.9 und versuchen Sie dann, eine FTP-Verbindung zu diesem Server herzustellen. Ich verwende FTP und Port 21 nur, weil ich unter Windows bin und einen FTP-Client habe, aber keinen Telnet-Client zur Hand.
Unterbrechen Sie dann von der Client-Seite einfach die Verbindung. (Ich mache nur Strg-C)
Bei Verwendung von Node v0.9.9 sollte NO ERROR und bei Verwendung von Node v.0.9.10 und höher KEIN FEHLER angezeigt werden.
In der Produktion verwende ich v.0.10. etwas und es gibt immer noch den Fehler. Auch hier denke ich, dass dies beabsichtigt ist und die Lösung darin besteht, den Fehler in Ihrem Code zu behandeln.
quelle
Hatte heute das gleiche Problem. Nach einigen Recherchen fand ich eine sehr nützliche
--abort-on-uncaught-exception
node.js Option . Es bietet nicht nur eine ausführlichere und nützlichere Ablaufverfolgung für Fehlerstapel, sondern speichert auch die Kerndatei beim Absturz der Anwendung und ermöglicht so ein weiteres Debuggen.quelle
Ich hatte das gleiche Problem, aber ich habe es gemildert, indem ich Folgendes platziert habe:
vorher
server.listen
.server
ist hier ein HTTP-Server. Das Standardzeitlimit beträgt 2 Minuten gemäß API-Dokumentation .quelle
Ein anderer möglicher Fall (aber selten) könnte sein, wenn Sie Server-zu-Server-Kommunikation haben und eingestellt haben
server.maxConnections
und einen sehr niedrigen Wert eingestellt haben.Im Kern lib lib.js des Knotens wird aufgerufen,
clientHandle.close()
was ebenfalls den Fehler ECONNRESET verursacht:quelle
maxConnections
Standardwert istInfinity
. Dies wäre (wie Sie sagten) nur dann der Fall, wenn Sie diesen Wert explizit überschrieben haben.Ja, Ihre Bereitstellung der Richtliniendatei kann definitiv zum Absturz führen.
Um dies zu wiederholen, fügen Sie Ihrem Code einfach eine Verzögerung hinzu:
… Und verwenden
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 auslöst.Um den Absturz hier zu vermeiden, fügen Sie einfach einen Fehlerbehandler hinzu, bevor Sie den Socket lesen / schreiben:
Wenn Sie versuchen, die oben genannte Verbindung zu trennen, wird anstelle eines Absturzes nur eine Protokollmeldung angezeigt.
Und wenn Sie fertig sind, denken Sie daran, die Verzögerung zu entfernen.
quelle
Ich erhalte auch einen ECONNRESET-Fehler während meiner Entwicklung. Die Art und Weise, wie ich ihn löse, besteht darin, dass ich meinen Server nicht mit nodemon starte. Nur
"node server.js"
zum Starten meines Servers wurde mein Problem behoben.Es ist komisch, aber es hat bei mir funktioniert, jetzt sehe ich den ECONNRESET-Fehler nie wieder.
quelle
Ich hatte auch diesen Fehler und konnte ihn nach Tagen des Debuggens und Analysierens beheben:
meine Lösung
Für mich war VirtualBox (für Docker) das Problem. Ich hatte die Portweiterleitung auf meiner VM konfiguriert und der Fehler trat nur am weitergeleiteten Port auf.
allgemeine Schlussfolgerungen
Die folgenden Beobachtungen können Ihnen Arbeitstage ersparen, die ich investieren musste:
-> Finden Sie heraus, ob etwas mit Ihrem Netzwerk (-Einstellungen) herumspielt, wie z. B. VMs, Firewalls usw., dies ist wahrscheinlich die Ursache des Problems.
quelle
Ich habe das Problem gelöst, indem ich mich einfach mit einem anderen Netzwerk verbunden habe . Das ist eines der möglichen Probleme.
Wie oben erläutert , ECONNRESET bedeutet , dass die TCP-Konversation 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.
quelle
Ich hatte dieses Problem gelöst durch:
npm update
im Terminal, um npm zu aktualisieren.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 benutze CENTOS 7
quelle
Ich hatte das gleiche Problem und es scheint, dass die Node.js-Version das Problem war.
Ich habe die vorherige Version von Node.js (10.14.2) installiert und mit nvm war alles in Ordnung (Sie können mehrere Versionen von Node.js installieren und schnell von einer Version zu einer anderen wechseln).
Es ist keine "saubere" Lösung, aber es kann Ihnen vorübergehend dienen.
quelle
Ich habe das gerade herausgefunden, zumindest in meinem Anwendungsfall.
Ich wurde
ECONNRESET
. Es stellte sich heraus, dass mein Client so eingerichtet war, dass er sehr schnell mit einem API-Aufruf auf den Server traf - und dass er den Endpunkt nur einmal erreichen musste.Als ich das behoben habe, war der Fehler weg.
quelle
Versuchen Sie, diese Optionen zu socket.io hinzuzufügen:
Ich hoffe, dies wird dir helfen !
quelle