Відповіді:
Інші відповіді справді божевільні, як ви можете прочитати у власних документах Node за адресою 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
, що очікує на анулювання, його буде видалено, оскільки нова заміна буде встановлена, як зазначено в Документації до Вузла
Цей модуль очікує на депресію. Після завершення завершення API 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
документи мають надійну інформацію про вихід / обробки помилок програмно.
Використання пробного лову може вирішити неприховані помилки, але в деяких складних ситуаціях це не виконає роботу, як-от ловіння функції асинхронізації. Пам'ятайте, що у "Вузлі" будь-які виклики функції асинхронізації можуть містити потенційну операцію збою програми.
Використання uncaughtException
є способом вирішення, але воно визнається неефективним і, ймовірно, буде видалено у майбутніх версіях Node, тому не розраховуйте на нього.
Ідеальним рішенням є використання домену: http://nodejs.org/api/domain.html
Щоб переконатися, що ваш додаток працює, навіть ваш сервер вийшов з ладу, виконайте наступні дії:
використовувати кластер вузлів для розщеплення декількох процесів на ядро. Отже, якщо один процес загинув, інший процес буде автоматично завантажений. Перевірте: http://nodejs.org/api/cluster.html
використовувати домен, щоб ловити операцію асинхронізації замість того, щоб пробувати ловити або виконувати без уваги. Я не кажу, що спроба лову або невдаху - це погана думка!
використовувати навіки / супервізор для контролю ваших послуг
додайте демон для запуску програми на вузлі: http://upstart.ubuntu.com
сподіваюся, що це допомагає!
Спробуйте модуль вузла pm2, він цілком відповідає і має чудову документацію. Менеджер виробничих процесів для додатків Node.js із вбудованим балансиром навантаження. будь ласка, уникайте невластивоговиконання цієї проблеми. https://github.com/Unitech/pm2
UncaughtException - це "дуже сильний механізм" (так правда), і домени тепер застарілі. Однак нам все-таки потрібен якийсь механізм, щоб вловлювати помилки навколо (логічних) доменів. Бібліотека:
https://github.com/vacuumlabs/yacol
може допомогти вам це зробити. Маючи трохи зайвого написання, ви можете мати приємну семантику домену по всьому коду!
Чудово працює на рестифікувати:
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();
});