Для автозапуска приложений Node.js есть много способов, но после некоторых поисков мне удалось отыскать такое решение, которое и работает, и не представляет большой трудности.
Сперва я испробовалforever — работает превосходно, но только до тех пор, пока вам не понадобится запустить приложение при начальной загрузке системы. Я пробовал добавить строчку в /etc/rc.d/rc.local — иногда она срабатывала, а иногда нет, и до сих пор я не разобрался, почему так.
Затем я поглядел на Upstartи на Monit. Upstart сделал сочинение скрипта для автозагрузчика таким же простым, как autoexec.bat во времена DOS, а Monit умеет проверять приложение, чтобы убедиться, что оно всё время работает.
Тут я понял, что моя потребность проста:во-первых, запускать приложение при начальной загрузке системы, а во-вторых, перезапускать, если оно упадёт (с приложениями Node.js такое случается) — и одного upstart достаточно для того, чтобы устроить и то, и другое.
В состав CentOS 6.2 upstart ужé входит, так что вам остаётся только поместить текстовый файлв /etc/init — назвав его, например, myapp.conf:
После этого можно будет подавать такие команды:
Приложение также будет запущено при начальной загрузке, и в CentOS 6.2 можно обойтись одним этим для запуска приложения и для поддержания его работы. Я обнаружил также, что в CentOS запуск посредствомrunlevel [2345] необходим, а другие варианты, кажется, не работают.
Примечания переводчика:
Сперва я испробовал
Затем я поглядел на Upstart
Тут я понял, что моя потребность проста:
В состав CentOS 6.2 upstart ужé входит, так что вам остаётся только поместить текстовый файл
#!upstart
description "testjs.js "
author "sample"
start on runlevel [2345]
stop on shutdown
respawn
script
export HOME="/root"
echo $$ > /var/run/testjs.pid
exec /usr/local/bin/node /root/test.js >> /var/log/testjs.log 2>&1
end script
pre-start script
# Формат даты тот же, что и у (new Date()).toISOString(), а не отсебятина
echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Starting" >> /var/log/testjs.log
end script
pre-stop script
rm /var/run/testjs.pid
echo "[`date -u +%Y-%m-%dT%T.%3NZ`] (sys) Stopping" >> /var/log/testjs.log
end script
После этого можно будет подавать такие команды:
/sbin/start myapp
/sbin/stop myapp
/sbin/status myapp
Приложение также будет запущено при начальной загрузке, и в CentOS 6.2 можно обойтись одним этим для запуска приложения и для поддержания его работы. Я обнаружил также, что в CentOS запуск посредством
Примечания переводчика:
- Upstart не нуждается в полях description
и author, так что можно обойтись в скрипте без них вместо того, чтобы наполнять всякой чепухою.
- Если пути в системе прописаны корректно, то в скрипте можно набирать просто
«node» вместо«/usr/local/bin/node»; то же самое касается и команд«start», «stop» и «status», которые тогда не будут нуждаться в префиксе«/sbin/».
- Помимо вышеперечисленных, существует также команда
«restart», которая запускает сперва«stop», а затем«start». Она бывает полезна в тех случаях, когда приходится одной командою (а не двумя) перезапустить, например, серверExpress.js, чтобы очиститькакой-нибудь такой кэш, который у сервера хранится в памяти, или чтобы принудить сервер руководствоваться новой версией джаваскриптового файла, описывающего маршрутизацию на сайте.
- Команду
«start» можно подавать без страха: она откажется работать, если приложение с указанным ей именем ужé запущено, а не запустит ненужный второй экземпляр его.
- Без строчки
«echo $$ > /var/run/testjs.pid» и без противоположной ей команды«rm /var/run/testjs.pid», как правило, можно обойтись. Убивать процесс по его номеру не придётся: куда проще подавать команду«stop» (или «restart»), в которой используется имя приложения, которое всегда одно и то же, да притом и запоминается лучше.
- Указание «respawn» работает в upstart так хорошо, что все обычные методы выхода из джаваскриптового приложения (например,
«process.exit(0)») также приводят к его перезапуску, а не к окончательной остановке. Можете воспользоваться этим, если понадобится предусмотреть интерфейс для дистанционного перезапускавеб-сервера или какого-нибудь другого сервера.
Вот упрощённый (но работающий) пример для Express.js:
app.get('/тайный_адрес_перезагрузчика', function(req, res){ res.type('text/plain'); res.send('The Express.js web server will shut down (and restart) in a second.'); console.log('Remote shutdown.'); setTimeout(function(){ process.exit(0); }, 1000); });