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