Ответы:
Другие ответы действительно безумны, так как вы можете прочитать их в собственных документах по адресу http://nodejs.org/docs/latest/api/process.html#process_event_uncaughtexception
Если кто-то использует другие заявленные ответы, прочитайте Node Docs:
Обратите внимание, что
uncaughtException
это очень грубый механизм обработки исключений, который может быть удален в будущем.
PM2
Прежде всего, я очень рекомендую установить PM2
для Node.js
. PM2 действительно отлично справляется с обработкой сбоев и мониторингом приложений Node, а также с балансировкой нагрузки. PM2 немедленно запускает приложение Node в случае его сбоя, остановки по любой причине или даже после перезапуска сервера. Так что, если когда-нибудь, даже после управления нашим кодом, произойдет сбой приложения, PM2 может перезапустить его немедленно. Для получения дополнительной информации, Установка и запуск PM2
Теперь вернемся к нашему решению по предотвращению сбоя самого приложения.
Так что после прохождения я наконец-то пришел к выводу, что сам документ Node предлагает:
Не следует использовать
uncaughtException
, использоватьdomains
сcluster
вместо этого. Если вы используетеuncaughtException
, перезапустите приложение после каждого необработанного исключения!
ДОМЕН с кластером
Что мы на самом деле делаем, так это отправляем ответ об ошибке на запрос, который вызвал ошибку, позволяя остальным закончить в обычное время и прекратить прослушивать новые запросы в этом работнике.
Таким образом, использование домена идет рука об руку с модулем кластера, так как мастер-процесс может разветвлять нового работника, когда работник сталкивается с ошибкой. Посмотрите код ниже, чтобы понять, что я имею в виду
Используя Domain
гибкость и разделяя нашу программу на несколько рабочих процессов Cluster
, мы можем более адекватно реагировать и обрабатывать ошибки с гораздо большей безопасностью.
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);
}
Несмотря на то, Domain
что ожидается устаревшая версия, она будет удалена, так как новая замена выполняется в соответствии с документацией Node.
Этот модуль ожидает устаревания. После завершения замены API этот модуль будет полностью устаревшим. Пользователи, которые обязательно должны иметь функциональные возможности, которые предоставляют домены, могут в настоящее время полагаться на него, но должны ожидать перехода на другое решение в будущем.
Но пока новая замена не будет введена, Домен с Кластером - единственное хорошее решение, которое предлагает Документация узла.
Для глубокого понимания Domain
и Cluster
чтения
https://nodejs.org/api/domain.html#domain_domain (Stability: 0 - Deprecated
)
https://nodejs.org/api/cluster.html
Спасибо @Stanley Luo за то, что поделились этим замечательным подробным объяснением о кластере и доменах.
restart your application after every unhandled exception!
Если 2000 пользователей используют веб-сервер узла для потоковой передачи видео, а 1 пользователь получил исключение, то перезапуск не будет прерывать всех остальных пользователей?
uncaughtException
и использовать Domain
с Cluster
вместо так, если один пользователь сталкивается исключение , чтобы только его поток удаляется из кластера и создал новый для него. И вам не нужно перезагружать сервер Node. Находясь на другой стороне, если вы используете, uncaughtException
вы должны перезапускать сервер каждый раз, когда любой из ваших пользователей сталкивается с проблемой. Итак, используйте домен с кластером.
domain
полностью устарели и удалены?
Я поместил этот код прямо под мои требования и глобальные объявления:
process.on('uncaughtException', function (err) {
console.error(err);
console.log("Node NOT Exiting...");
});
работает для меня. единственное, что мне не нравится в этом, - это то, что я не получаю так много информации, как если бы я просто позволил вещи рухнуть.
forever
или что-то в этом роде.
Как упомянуто здесь, вы найдете error.stack
более полное сообщение об ошибке, например номер строки, вызвавшей ошибку:
process.on('uncaughtException', function (error) {
console.log(error.stack);
});
Пытаться supervisor
npm install supervisor
supervisor app.js
Или вы можете установить forever
вместо.
Все, что вам нужно сделать, это восстановить ваш сервер в случае сбоя, перезапустив его.
forever
может использоваться в коде, чтобы корректно восстанавливать любые процессы, которые аварийно завершают работу.
В forever
документы имеют надежную информацию о выходе / обработки ошибок программно.
Использование try-catch может решить необработанные ошибки, но в некоторых сложных ситуациях он не будет работать правильно, например, перехват асинхронной функции. Помните, что в Node любые вызовы асинхронных функций могут содержать потенциальную операцию сбоя приложения.
Использование uncaughtException
- это обходной путь, но оно признано неэффективным и, вероятно, будет удалено в будущих версиях Node, поэтому не рассчитывайте на это.
Идеальным решением является использование домена: http://nodejs.org/api/domain.html
Чтобы убедиться, что ваше приложение запущено и работает даже при сбое сервера, выполните следующие действия:
используйте кластер узлов для раскрутки нескольких процессов на ядро. Таким образом, если один процесс умер, другой процесс будет автоматически загружаться. Проверьте: http://nodejs.org/api/cluster.html
используйте домен для перехвата асинхронной операции вместо использования try-catch или uncaught. Я не говорю, что попытка поймать или не поймать - плохая мысль!
использовать навсегда / супервизор для мониторинга ваших услуг
добавьте демон для запуска приложения вашего узла: http://upstart.ubuntu.com
надеюсь это поможет!
Попробуйте модуль узла pm2, он достаточно последовательный и имеет отличную документацию. Менеджер производственного процесса для приложений Node.js со встроенным балансировщиком нагрузки. пожалуйста, избегайте uncaughtException для этой проблемы. https://github.com/Unitech/pm2
UncaughtException - это «очень грубый механизм» (так верно), и домены сейчас устарели. Однако нам все еще нужен какой-то механизм для выявления ошибок вокруг (логических) доменов. Библиотека:
https://github.com/vacuumlabs/yacol
могу помочь тебе сделать это Приложив немного лишних усилий, вы можете иметь хорошую семантику домена по всему коду!
Отлично работает на restify:
server.on('uncaughtException', function (req, res, route, err) {
log.info('******* Begin Error *******\n%s\n*******\n%s\n******* End Error *******', route, err.stack);
if (!res.headersSent) {
return res.send(500, {ok: false});
}
res.write('\n');
res.end();
});