Node.js / Express.js отлично подходит для веб-API и приложений. В отличие от известных корпоративных технологий, Node.js очень особенный. Это единый процесс / многопоточная среда. Если возникает незапланированное исключение, виртуальная машина Node.js просто останавливается, оставляя приложение в не отвечающем состоянии.
Из-за async
природы Node.js try/catch
не всегда работает, даже если у domains
вас есть шанс, что у вас произойдет сбой приложения во время сна.
Чтобы смягчить проблему, существует несколько известных решений . Общая идея состоит в том, что есть сторожевой таймер, следящий за node
процессами, и в случае сбоя он перезапускает приложение снова.
Недавно я использовал замечательную библиотеку @mafintosh под названием respawn . Мне понравился его минималистичный стиль, и я решил попробовать его.
Базовый код очень прост. Без изменения вашего приложения просто создайте файл monitor.js
со следующим кодом:
var respawn = require('respawn'); var monitor = respawn(['node', 'server.js'], { env: {ENV_VAR:'test'}, // set env vars cwd: '.', // set cwd maxRestarts:10, // how many restarts are allowed within 60s sleep:1000, // time to sleep between restarts }); monitor.start(); // spawn and watch
monitor
вызовет новый процесс узла и в случае сбоя будет перезапущен. Вы также можете указать maxRestars
(я рекомендую это сделать, если что-то действительно плохое, оно не будет перезапущено бесконечно) и sleep
время.
Я попробовал это, реализовав /fail
конечную точку в своем приложении, чтобы убедиться, что это respawn
действительно работает.
app.get('/fail', function (req, res, next) { setTimeout(function () { var nu = null; nu.access(); res.send('Hello World'); }, 1000); });
если я попытаюсь нажать, /fail
я не вижу результатов в браузере, но если я вернусь к /
приложению, оно работает в нормальном состоянии.
Но простое повторное создание приложения не является полным решением. Вы должны знать, что именно случилось, чтобы решить проблему. Правильная регистрация вашего приложения имеет важное значение. Я покажу свою маленькую настройку, respawn
которая посылает критическое сообщение Logentries , так что все сбои регистрируются.
var respawn = require('respawn'); var util = require('util'); var logger = require('./source/utils/logger'); var proc = respawn(['node', 'app.js'], { cwd: '.', maxRestarts: 10, sleep: 1000, }); proc.on('spawn', function () { util.print('application monitor started...'); }); proc.on('exit', function (code, signal) { logger.fatal({msg: 'process exited, code: ' + code + ' signal: ' + signal}); }); proc.on('stdout', function (data) { util.print(data.toString()); }); proc.on('stderr', function (data) { logger.error({msg: 'process error', data: data.toString()}); }); proc.start();
(Подробную информацию о регистраторе вы можете найти в этом посте ).
Весь процесс выводится stdout
, что удобно для разработки, но в случае stderr
или exit
все записывается в облако и dev-team
отправляется уведомление .
Это сработало очень хорошо, теперь я не волнуюсь, даже если на производстве случается что-то плохое. respawn
позаботится о том, чтобы остальные пользователи не пострадали. Как разработчик, вы можете гораздо быстрее находить ошибки и устанавливать исправления.