Статьи

Как сохранить процессы Node.js запущенными

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позаботится о том, чтобы остальные пользователи не пострадали. Как разработчик, вы можете гораздо быстрее находить ошибки и устанавливать исправления.