Korzystam z aplikacji Express.js za pomocą Socket.io dla aplikacji internetowej do czatu i następujący błąd pojawia się losowo około 5 razy w ciągu 24 godzin. Proces węzła jest zawinięty na zawsze i natychmiast uruchamia się ponownie.
Problem polega na tym, że ponowne uruchomienie Express wykopuje moich użytkowników ze swoich pokoi i nikt tego nie chce.
Serwer WWW jest zarządzany przez HAProxy. Nie ma problemów ze stabilnością gniazd, po prostu używając transportów websockets i flashsockets. Nie mogę tego celowo powielić.
To jest błąd z Węzłem 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
EDYCJA (2013-07-22)
Dodano zarówno moduł obsługi błędów klienta socket.io, jak i moduł obsługi wyjątków nieprzechwyconych. Wydaje się, że ten łapie błąd:
process.on('uncaughtException', function (err) {
console.error(err.stack);
console.log("Node NOT Exiting...");
});
Podejrzewam więc, że to nie jest problem z Socket.io, ale żądanie HTTP do innego serwera, który robię, lub połączenie MySQL / Redis. Problem polega na tym, że stos błędów nie pomaga mi zidentyfikować problemu z kodem. Oto dane wyjściowe dziennika:
Error: read ECONNRESET
at errnoException (net.js:900:11)
at TCP.onread (net.js:555:19)
Skąd mam wiedzieć, co to powoduje? Jak uzyskać więcej z błędu?
Ok, niezbyt gadatliwy, ale oto stacktrace z 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] ] } }
Tutaj podaję plik strategii gniazda Flash:
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)
Czy to może być przyczyna?
Odpowiedzi:
Być może już go zgadłeś: to błąd połączenia.
„ECONNRESET” oznacza, że druga strona rozmowy TCP gwałtownie zamknęła swój koniec połączenia. Jest to najprawdopodobniej spowodowane jednym lub kilkoma błędami protokołu aplikacji. Możesz spojrzeć na dzienniki serwera API, aby zobaczyć, czy coś narzeka.
Ale ponieważ szukasz także sposobu sprawdzenia błędu i potencjalnego debugowania problemu, powinieneś rzucić okiem na „ Jak debugować błąd zawieszenia gniazda w NodeJS? ”, Który został opublikowany w stackoverflow w związku z podobnym pytaniem.
EDYCJA (2013-07-22)
Jak napisałem powyżej:
Co może być również prawdą: w przypadkowych momentach druga strona jest przeciążona i w rezultacie po prostu niszczy połączenie. W takim przypadku zależy to od tego, z czym się łączysz…
Ale jedno jest pewne: rzeczywiście masz błąd odczytu połączenia TCP, który powoduje wyjątek. Możesz to zobaczyć, patrząc na kod błędu, który opublikowałeś w swojej edycji, co go potwierdza.
źródło
Powodował to prosty serwer TCP do obsługi pliku zasad Flash. Teraz mogę złapać błąd za pomocą modułu obsługi:
źródło
socket.destroy()
się upewniałem w module obsługi błędów. Niestety nie mogę znaleźć dokumentacji, czy jest ona wymagana, ale nie powoduje to błędu.Miałem podobny problem, gdy aplikacje zaczęły występować błędy po aktualizacji Node. Myślę, że można to przypisać do wersji Node v0.9.10 tego elementu:
Poprzednie wersje nie błędnie informowały o przerwach od klienta. Przerwanie połączenia od klienta powoduje zgłoszenie błędu ECONNRESET w węźle. Wierzę, że jest to zamierzona funkcjonalność dla Węzła, więc poprawka (przynajmniej dla mnie) polegała na obsłudze błędu, który, jak sądzę, zrobiłeś w wyjątkach nieprzechwyconych. Chociaż obsługuję to w module obsługi net.socket.
Możesz to zademonstrować:
Utwórz prosty serwer gniazd i pobierz Node v0.9.9 i v0.9.10.
Uruchom go za pomocą wersji 0.9.9, a następnie spróbuj wysłać FTP na ten serwer. Używam FTP i portu 21 tylko dlatego, że korzystam z systemu Windows i mam klienta FTP, ale nie ma pod ręką klienta telnet.
Następnie ze strony klienta po prostu przerwij połączenie. (Właśnie wykonuję Ctrl + C)
Powinieneś zobaczyć BRAK BŁĘDU podczas korzystania z Węzła w wersji 0.9.9 i BŁĄD podczas używania Węzła w wersji 0.9.10 i nowszych.
W produkcji używam wersji v0.10. coś i nadal daje błąd. Ponownie myślę, że jest to zamierzone, a rozwiązaniem jest poradzenie sobie z błędem w kodzie.
źródło
Miałem dzisiaj ten sam problem. Po niektórych badań znalazłem bardzo przydatnych
--abort-on-uncaught-exception
opcji node.js . Nie tylko zapewnia dużo bardziej szczegółowe i przydatne śledzenie stosu błędów, ale także zapisuje plik podstawowy po awarii aplikacji, umożliwiając dalsze debugowanie.źródło
Napotkałem ten sam problem, ale złagodziłem go, umieszczając:
przed
server.listen
.server
jest tutaj serwer HTTP. Domyślny limit czasu wynosi 2 minuty zgodnie z dokumentacją interfejsu API .źródło
Innym możliwym przypadkiem (ale rzadkim) może być sytuacja, gdy masz komunikację między serwerami i masz
server.maxConnections
bardzo niską wartość.W rdzeniu biblioteki lib net.js zadzwoni,
clientHandle.close()
co również spowoduje błąd ECONNRESET:źródło
maxConnections
domyślna wartość toInfinity
. Byłoby tak tylko w przypadku (jak powiedziałeś), jeśli wyraźnie zastąpiłeś tę wartość.Tak, podanie pliku zasad może z pewnością spowodować awarię.
Aby powtórzyć, po prostu dodaj opóźnienie do swojego kodu:
… I użyj,
telnet
aby połączyć się z portem. Jeśli rozłączysz telnet przed upływem opóźnienia, nastąpi awaria (nieprzechwycony wyjątek), gdy socket.write zgłosi błąd.Aby uniknąć awarii, po prostu dodaj moduł obsługi błędów przed odczytem / zapisem gniazda:
Gdy spróbujesz powyższego rozłączyć, po prostu otrzymasz komunikat dziennika zamiast awarii.
A kiedy skończysz, pamiętaj o usunięciu opóźnienia.
źródło
Podczas programowania pojawia się również błąd ECONNRESET. Sposób, w jaki go rozwiązuję, polega na tym, że nie uruchamiam serwera za pomocą nodemon, po prostu użyj go,
"node server.js"
by uruchomić mój serwer, naprawiłem mój problem.To dziwne, ale zadziałało dla mnie, teraz już nigdy nie widzę błędu ECONNRESET.
źródło
Miałem również ten błąd i byłem w stanie go rozwiązać po dniach debugowania i analizy:
moje rozwiązanie
Dla mnie problem stanowił VirtualBox (dla Dockera). Miałem Port Forwarding skonfigurowane na mojej maszynie wirtualnej, a błąd wystąpił tylko na przekazanym porcie.
ogólne wnioski
Następujące obserwacje mogą zaoszczędzić Ci dni pracy, które musiałem zainwestować:
-> dowiedz się, czy coś nie działa w twojej sieci (ustawienia), takie jak maszyny wirtualne, zapory ogniowe itp., prawdopodobnie jest to przyczyną problemu.
źródło
Rozwiązałem problem, po prostu podłączając się do innej sieci . To jeden z możliwych problemów.
Jak omówiono powyżej, ECONNRESET oznacza, że rozmowa TCP gwałtownie zamknęła koniec połączenia.
Twoje połączenie internetowe może blokować dostęp do niektórych serwerów. W moim przypadku próbowałem połączyć się z mLab (usługa bazy danych w chmurze, która obsługuje bazy danych MongoDB). A mój dostawca usług internetowych to blokuje.
źródło
Rozwiązałem ten problem przez:
npm update
w terminalu, aby zaktualizować npm.Potem wypróbowałem to samo polecenie npm i dobrze, że się udało. Nie byłem pewien, czy to takie proste.
Używam CENTOS 7
źródło
Miałem ten sam problem i wygląda na to, że problem stanowiła wersja Node.js.
Zainstalowałem poprzednią wersję Node.js (10.14.2) i wszystko było w porządku przy użyciu nvm (pozwala zainstalować kilka wersji Node.js i szybko przełączać się z jednej wersji na inną).
Nie jest to „czyste” rozwiązanie, ale może ci służyć tymczasowo.
źródło
Właśnie to rozgryzłem, przynajmniej w moim przypadku użycia.
Dostawałem
ECONNRESET
. Okazało się, że sposób, w jaki skonfigurowano mojego klienta, bardzo szybko uderzał w serwer wywołaniem API naprawdę wiele razy - i wystarczyło tylko raz trafić punkt końcowy.Kiedy to naprawiłem, błąd zniknął.
źródło
Spróbuj dodać te opcje do socket.io:
Mam nadzieję, że to Ci pomoże !
źródło