Inne odpowiedzi są naprawdę szalone, o czym można przeczytać w dokumentach Node pod adresem http://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception
Jeśli ktoś używa innych podanych odpowiedzi, przeczytaj Node Docs:
Zauważ, że uncaughtException
jest to bardzo prymitywny mechanizm obsługi wyjątków i może zostać usunięty w przyszłości
PM2
Przede wszystkim gorąco polecam zainstalowanie PM2
na Node.js
. PM2 świetnie radzi sobie z awariami i monitorowaniem aplikacji Node, a także z równoważeniem obciążenia. PM2 natychmiast uruchamia aplikację Node w przypadku awarii, zatrzymania z dowolnego powodu lub nawet po ponownym uruchomieniu serwera. Tak więc, jeśli pewnego dnia, nawet po zarządzaniu naszym kodem, aplikacja ulegnie awarii, PM2 może ją natychmiast ponownie uruchomić. Więcej informacji: Instalowanie i uruchamianie PM2
Wróćmy teraz do naszego rozwiązania, które zapobiega awariom samej aplikacji.
Więc po przejściu w końcu doszedłem do tego, co sugeruje sam dokument Node:
Nie używać uncaughtException
, korzystanie domains
z cluster
zamiast. Jeśli używasz uncaughtException
, uruchom ponownie aplikację po każdym nieobsługiwanym wyjątku!
DOMAIN z klastrem
W rzeczywistości wysyłamy odpowiedź o błędzie na żądanie, które wywołało błąd, pozwalając innym zakończyć w ich normalnym czasie i przestać nasłuchiwać nowych żądań w tym procesie roboczym.
W ten sposób użycie domeny idzie ręka w rękę z modułem klastra, ponieważ proces główny może forować nowego pracownika, gdy pracownik napotka błąd. Zobacz poniższy kod, aby zrozumieć, o co mi chodzi
Używając Domain
i elastycznie dzieląc nasz program na wiele procesów roboczych Cluster
, możemy reagować lepiej i obsługiwać błędy z dużo większym bezpieczeństwem.
var cluster = require('cluster');
var PORT = +process.env.PORT || 1337;
if(cluster.isMaster)
{
cluster.fork();
cluster.fork();
cluster.on('disconnect', function(worker)
{
console.error('disconnect!');
cluster.fork();
});
}
else
{
var domain = require('domain');
var server = require('http').createServer(function(req, res)
{
var d = domain.create();
d.on('error', function(er)
{
//something unexpected occurred
console.error('error', er.stack);
try
{
//make sure we close down within 30 seconds
var killtimer = setTimeout(function()
{
process.exit(1);
}, 30000);
// But don't keep the process open just for that!
killtimer.unref();
//stop taking new requests.
server.close();
//Let the master know we're dead. This will trigger a
//'disconnect' in the cluster master, and then it will fork
//a new worker.
cluster.worker.disconnect();
//send an error to the request that triggered the problem
res.statusCode = 500;
res.setHeader('content-type', 'text/plain');
res.end('Oops, there was a problem!\n');
}
catch (er2)
{
//oh well, not much we can do at this point.
console.error('Error sending 500!', er2.stack);
}
});
//Because req and res were created before this domain existed,
//we need to explicitly add them.
d.add(req);
d.add(res);
//Now run the handler function in the domain.
d.run(function()
{
//You'd put your fancy application logic here.
handleRequest(req, res);
});
});
server.listen(PORT);
}
Chociaż Domain
oczekuje na wycofanie i zostanie usunięty, gdy nowy zamiennik pojawi się zgodnie z dokumentacją Node
Ten moduł oczekuje na wycofanie. Po sfinalizowaniu zastępczego interfejsu API ten moduł zostanie całkowicie wycofany. Użytkownicy, którzy bezwzględnie muszą mieć funkcjonalność zapewnianą przez domeny, mogą na razie na niej polegać, ale powinni spodziewać się migracji do innego rozwiązania w przyszłości.
Jednak dopóki nowy zamiennik nie zostanie wprowadzony, Domain with Cluster jest jedynym dobrym rozwiązaniem, które sugeruje Node Documentation.
Aby dogłębnie zrozumieć Domain
i Cluster
przeczytać
https://nodejs.org/api/domain.html#domain_domain (Stability: 0 - Deprecated
)
https://nodejs.org/api/cluster.html
Dziękujemy @Stanley Luo za udostępnienie nam tego wspaniałego, dogłębnego wyjaśnienia na temat klastrów i domen
Klaster i domeny
restart your application after every unhandled exception!
W przypadku, gdy 2000 użytkowników korzysta z serwera WWW węzła do przesyłania strumieniowego wideo, a 1 użytkownik dostał wyjątek, to ponowne uruchomienie nie przerwie pracy wszystkich innych użytkowników?uncaughtException
i używanieDomain
z nim jest złeCluster
, więc jeśli jeden użytkownik napotka wyjątek, tylko jego wątek zostanie usunięty z klastra i utworzy dla niego nowy. Nie musisz też ponownie uruchamiać serwera Node. Będąc po drugiej stronie, jeśli używaszuncaughtException
, musisz ponownie uruchomić serwer za każdym razem, gdy którykolwiek z użytkowników napotka problem. Dlatego użyj domeny z klastrem.domain
zostanie całkowicie wycofany i usunięty?cluster
iworkers
: sitepoint.com/…Umieściłem ten kod bezpośrednio pod moimi wymaganiami i deklaracjami globalnymi:
pracuje dla mnie. jedyne, co mi się w tym nie podoba, to to, że nie dostaję tylu informacji, ile bym, gdybym pozwolił, żeby coś się zawiesiło.
źródło
forever
czy czegoś podobnego.Jak wspomniano tutaj , znajdziesz
error.stack
bardziej kompletny komunikat o błędzie, taki jak numer wiersza, który spowodował błąd:źródło
Próbować
supervisor
Lub możesz
forever
zamiast tego zainstalować .Wszystko to spowoduje odzyskanie serwera po awarii przez ponowne uruchomienie.
forever
może być używany w kodzie, aby bezpiecznie odzyskać wszelkie awarie procesów.Dokumentacja
forever
zawiera solidne informacje o programowej obsłudze wyjścia / błędów.źródło
Użycie try-catch może rozwiązać niezłapane błędy, ale w niektórych złożonych sytuacjach nie będzie działać poprawnie, na przykład przechwytywanie funkcji asynchronicznej. Pamiętaj, że w Node każde wywołanie funkcji asynchronicznej może zawierać potencjalną operację awarii aplikacji.
Używanie
uncaughtException
jest obejściem, ale jest uznawane za nieefektywne i prawdopodobnie zostanie usunięte w przyszłych wersjach Node, więc nie licz na to.Idealnym rozwiązaniem jest użycie domeny: http://nodejs.org/api/domain.html
Aby upewnić się, że aplikacja działa i działa nawet w przypadku awarii serwera, wykonaj następujące czynności:
użyj klastra węzłów do rozwidlenia wielu procesów na rdzeń. Więc jeśli jeden proces umarł, inny proces zostanie automatycznie uruchomiony. Sprawdź: http://nodejs.org/api/cluster.html
użyj domeny do przechwycenia operacji asynchronicznej zamiast używania try-catch lub uncatcht. Nie mówię, że próba złapania lub nie złapany to zła myśl!
używaj na zawsze / Supervisor do monitorowania swoich usług
dodaj demona do uruchamiania aplikacji węzła: http://upstart.ubuntu.com
mam nadzieję że to pomoże!
źródło
Wypróbuj moduł węzła pm2, jest on spójny i ma świetną dokumentację. Menedżer procesów produkcyjnych dla aplikacji Node.js z wbudowanym systemem równoważenia obciążenia. proszę unikać wyjątku uncaughtException dla tego problemu. https://github.com/Unitech/pm2
źródło
UncaughtException to „bardzo prymitywny mechanizm” (tak prawdziwy), a domeny są teraz przestarzałe. Jednak nadal potrzebujemy mechanizmu do wychwytywania błędów wokół (logicznych) domen. Biblioteka:
https://github.com/vacuumlabs/yacol
może ci w tym pomóc. Przy odrobinie dodatkowego pisania możesz mieć ładną semantykę domeny w całym kodzie!
źródło
Działa świetnie na restify:
źródło