Как запустить Node.js в качестве фонового процесса и никогда не умирать?

480

Я подключаюсь к серверу Linux через замазку SSH. Я попытался запустить его в качестве фонового процесса, как это:

$ node server.js &

Однако через 2,5 часа терминал становится неактивным, и процесс умирает. Могу ли я в любом случае поддерживать процесс, даже если терминал отключен?


Редактировать 1

На самом деле, я пытался nohup, но как только я закрываю терминал Putty SSH или отключаю интернет, серверный процесс сразу останавливается.

Что-нибудь, что я должен сделать в Замазке?


Изменить 2 (февраль 2012 г.)

Есть node.jsмодуль, навсегда . Он будет запускать сервер node.js как сервис-демон.

murvinlai
источник
7
В моем случае nohup работает, когда я выхожу из терминала, печатая exit. Когда я просто закрываю окно Putty, это не удается.
Павел Фурманьяк

Ответы:

513

Простое решение (если вы не хотите возвращаться к процессу, просто хотите, чтобы оно продолжалось):

nohup node server.js &

Также есть jobsкоманда, чтобы увидеть индексированный список этих фоновых процессов. И вы можете убить фоновый процесс, запустив его kill %1или kill %2указав номер, являющийся индексом процесса.

Мощное решение (позволяет повторно подключиться к процессу, если он интерактивный):

screen

Затем вы можете отсоединиться, нажав Ctrl + a + d, а затем присоединиться обратно, запустив screen -r

Также рассмотрите более новую альтернативу screen, tmux.

Тип машины
источник
1
Итак, если я запускаю «экран», я создаю экран и запускаю его, верно?
Мурвинлай
30
да, а затем вы можете отсоединиться, нажав Ctrl + a, d, а затем присоединиться обратно, выполнив screen -r
MK.
1
@murvinlai EC2 - это среда, которая не имеет ничего общего с привилегиями суперпользователя. Это, наверное, о твоем AMI. Например, с Amazon AMI вы, конечно, можете sudo bash.
ShuaiYuan
1
man bash: если команда завершается оператором управления &, оболочка выполняет команду в фоновом режиме в подоболочке. Оболочка не ожидает завершения выполнения команды, и статус возврата равен 0.
MK.
34
Пожалуйста, всем, кто читает это: запуск сервера node.js в сеансе screen или tmux - это решение AMATEUR ! Не делайте этого, если только для быстрых тестов. Чтобы процесс продолжался, вам нужно его демонизировать ! Используйте надлежащие инструменты для него, как и навсегда , PM2 или равнинных старых скриптов init.d .
Виктор Шредер
1119

nohup node server.js > /dev/null 2>&1 &

  1. nohupозначает: не прекращайте этот процесс, даже если stty отключен.
  2. > /dev/nullозначает: stdout идет в / dev / null (это фиктивное устройство, которое не записывает какой-либо вывод).
  3. 2>&1означает: stderr также переходит в стандартный вывод (который уже перенаправлен /dev/null). Вы можете заменить & 1 на путь к файлу, чтобы вести журнал ошибок, например:2>/tmp/myLog
  4. &в конце означает: запустить эту команду в качестве фоновой задачи.
Йоши
источник
49
Это должен быть принятый ответ, потому что он гораздо более высокого качества, чем принятый в настоящее время.
L0j1k
2
@ L0j1k дискуссионный, OP продемонстрировал уровень понимания того, что для принятого ответа требуется дальнейшее объяснение.
JFA
41
SO не столько о OP, сколько о тысячах людей, обращающихся к OP за помощью.
L0j1k
3
Нужно ли перенаправлять stdout и stderr? Будет ли это работать так же хорошо, если я вообще их не перенаправлю? Или если я перенаправил их в файлы вместо этого?
Шон
10
Отправить стандартный вывод и стандартный вывод /dev/null? Хорошая регистрация ... Удачи в попытке отладить это ...
Виктор Шредер
138

Вы действительно должны попытаться использовать screen. Это немного сложнее, чем просто делать nohup long_running &, но понять экран, как только вы никогда не вернетесь.

Сначала запустите сеанс экрана:

user@host:~$ screen

Запустите все, что вы хотите:

wget http://mirror.yandex.ru/centos/4.6/isos/i386/CentOS-4.6-i386-binDVD.iso

Нажмите Ctrl + A и затем d. Выполнено. Ваша сессия продолжается в фоновом режиме.

Вы можете составить список всех сессий screen -lsи присоединиться к некоторым с помощью screen -r 20673.pts-0.srvкоманды, где 0673.pts-0.srv - это список записей.

Алекс Повар
источник
125

Это старый вопрос, но он высоко оценен в Google. Я почти не могу поверить в ответы с наибольшим количеством голосов, потому что запуск процесса node.js в сеансе экрана &с nohupфлагом или даже с флагом - все они - просто обходные пути.

Специально решение screen / tmux, которое действительно следует рассматривать как любительское решение. Screen и Tmux предназначены не для поддержки процессов, а для мультиплексирования сеансов терминала. Это нормально, когда вы запускаете скрипт на своем сервере и хотите отключиться. Но для сервера node.js вы не хотите, чтобы ваш процесс был подключен к терминальной сессии. Это слишком хрупко. Чтобы все работало, вам нужно демонизировать процесс!

Есть много хороших инструментов для этого.

PM2 : http://pm2.keymetrics.io/

# basic usage
$ npm install pm2 -g
$ pm2 start server.js

# you can even define how many processes you want in cluster mode:
$ pm2 start server.js -i 4

# you can start various processes, with complex startup settings
# using an ecosystem.json file (with env variables, custom args, etc):
$ pm2 start ecosystem.json

Одно большое преимущество, которое я вижу в пользу PM2, заключается в том, что он может генерировать сценарий запуска системы, чтобы процесс продолжался между перезапусками:

$ pm2 startup [platform]

Где platformможно ubuntu|centos|redhat|gentoo|systemd|darwin|amazon.

forever.js : https://github.com/foreverjs/forever

# basic usage
$ npm install forever -g
$ forever start app.js

# you can run from a json configuration as well, for
# more complex environments or multi-apps
$ forever start development.json

Сценарии инициализации :

Я не буду вдаваться в подробности о том, как написать сценарий инициализации, потому что я не являюсь экспертом в этом вопросе, и этот ответ будет слишком длинным, но в основном это простые сценарии оболочки, запускаемые событиями ОС. Вы можете прочитать больше об этом здесь

Докер :

Просто запустите ваш сервер в Docker-контейнере с -dопцией и, вуаля , у вас есть демонизированный сервер node.js!

Вот пример Dockerfile (из официального руководства node.js ):

FROM node:argon

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "start" ]

Затем создайте свой образ и запустите свой контейнер:

$ docker build -t <your username>/node-web-app .
$ docker run -p 49160:8080 -d <your username>/node-web-app

Надеюсь, это поможет кому-нибудь приземлиться на этой странице. Всегда используйте подходящий инструмент для работы. Это избавит вас от многих головных болей и лишних часов!

Виктор Шредер
источник
2
Это то, что я искал. С решением pm2 есть ли способ присоединить терминал к нему позже?
Квантование 15.07.16
4
@ Количество, нет. Это невозможно, потому что процесс не выполняется в интерактивном сеансе. Но вы можете испытывать то же «чувство», tail -fиспользуя файл журнала, который генерирует pm2.
Виктор Шредер
1
Вы указываете screenрешение, которое многие люди находят, а работа - это обходной путь. Есть много способов достижения конкретной задачи. Я полагаю, что это случается, что (рассмотрите конкретный вопрос), это, оказывается, достигает определенной задачи run as background and never dieпревосходного для многих. Он также имеет дополнительный бонус, позволяющий пользователю вернуться в него, чтобы вновь взаимодействовать и вносить изменения, если он хочет. Ключ это компоненты backgroundи есть never die. Все решения имеют определенные бонусы.
Л.Д. Джеймс
@ Ракшит Рави - я не согласен. Все это требует дополнительных загрузок / программного обеспечения / инструментов (кроме решения init, для которого не было дано никакого решения). nohup Это решение. Он встроен в Linux и предназначен для этого. Это одна строка, она чистая и работает как задумано, всегда, независимо от обновлений. Люди действительно должны стараться избегать использования сторонних инструментов для базовых сценариев использования, таких как этот. Пример докера (например) намного более многословен и ресурсоемок, чем одна простая команда в ответе с верхним голосом. Люблю докер, но не за это.
Jack_Hu
1
@Jack_Hu, я не сомневаюсь в накладных расходах, но nohupрешение не удовлетворяет требованию «никогда не умирать». Если вы не напишете очень хитрый trapили хакерский бесконечный цикл, я не пойму, как сохранить демонизированный процесс без использования инструментов, специально написанных для этой цели (или сценария инициализации, написанного вами, конечно).
Виктор Шредер,
24

другое решение отречься от работы

$ nohup node server.js &
[1] 1711
$ disown -h %1
myururdurmaz
источник
disown - это именно то, что я искал, но что делает флаг -h? Я не могу найти это в руководстве
Римантас Якикявичюс
со страницы man: если задана опция -h, каждая спецификация заданий не удаляется из таблицы, а помечается так, что SIGHUP не отправляется заданию, если оболочка получает SIGHUP. Если спецификация заданий не указана, опция -a означает удалить или отметить все задания;
Мюрурдурмаз
14

nohupпозволит программе продолжаться даже после смерти терминала. У меня действительно были ситуации, когдаnohup предотвращает корректное завершение сеанса SSH, поэтому вы должны также перенаправить ввод:

$ nohup node server.js </dev/null &

В зависимости от того, как nohupнастроено, вам также может понадобиться перенаправить стандартный вывод и стандартную ошибку в файлы.

Даниэль Галлахер
источник
7

У меня есть эта функция в моем rc-файле оболочки, основанная на ответе @ Yoichi:

nohup-template () {
    [[ "$1" = "" ]] && echo "Example usage:\nnohup-template urxvtd" && return 0
    nohup "$1" > /dev/null 2>&1 &
}

Вы можете использовать это так:

nohup-template "command you would execute here"
thiagowfx
источник
7

Nohup и screen предлагают отличные световые решения для запуска Node.js в фоновом режиме. Диспетчер процессов Node.js ( PM2 ) - удобный инструмент для развертывания. Установите его с помощью npm в вашей системе:

npm install pm2 -g

запустить приложение Node.js в качестве демона:

pm2 start app.js

При желании вы можете связать его с Keymetrics.io SAAS для мониторинга, разработанной Unitech.

Дональд Дерек
источник
6
$ disown node server.js &

Он удалит команду из списка активных задач и отправит команду в фоновый режим.

Skynet
источник
3

Чтобы запустить команду как системную службу в Debian с помощью sysv init:

Скопируйте скелетный скрипт и адаптируйте его под свои нужды, вероятно, все, что вам нужно сделать, это установить некоторые переменные. Ваш скрипт будет наследовать точные значения по умолчанию /lib/init/init-d-script, если что-то не соответствует вашим потребностям - переопределите это в вашем скрипте. Если что-то пойдет не так, вы можете увидеть детали в источнике /lib/init/init-d-script. Обязательные перемены есть DAEMONи NAME. Скрипт будет использовать start-stop-daemonдля запуска вашей команды, START_ARGSвы можете определить дополнительные параметры start-stop-daemonдля использования.

cp /etc/init.d/skeleton /etc/init.d/myservice
chmod +x /etc/init.d/myservice
nano /etc/init.d/myservice

/etc/init.d/myservice start
/etc/init.d/myservice stop

Вот как я запускаю некоторые вещи на Python для моей вики-сайта Викимедиа:

...
DESC="mediawiki articles converter"
DAEMON='/home/mss/pp/bin/nslave'
DAEMON_ARGS='--cachedir /home/mss/cache/'
NAME='nslave'
PIDFILE='/var/run/nslave.pid'
START_ARGS='--background --make-pidfile --remove-pidfile --chuid mss --chdir /home/mss/pp/bin'

export PATH="/home/mss/pp/bin:$PATH"

do_stop_cmd() {
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
        $STOP_ARGS \
        ${PIDFILE:+--pidfile ${PIDFILE}} --name $NAME
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2
    rm -f $PIDFILE
    return $RETVAL
}

Помимо установки vars мне пришлось переопределить, do_stop_cmdпотому что Python заменяет исполняемый файл, поэтому служба не остановилась должным образом.

user3132194
источник
3

Помимо крутых решений выше, я бы упомянул также о средствах supervisord и monit, которые позволяют запускать процесс, отслеживать его наличие и запускать, если он умер. С помощью 'monit' вы также можете запускать некоторые активные проверки, такие как проверка, отвечает ли процесс на запрос http

Кшиштоф Ксенежик
источник
3

Для Ubuntu я использую это:

(exec PROG_SH &> / dev / null &)

С уважением

Дэвид Лопес
источник
Незначительный момент: «exec» не требуется, если PROG_SH - исполняемый файл. Смысл решения, предложенного Дэвидом, состоит в том, чтобы отделить дочерний элемент от текущей запущенной оболочки. Родитель ребенка становится 'pid 1' и не будет затронут после завершения оболочки.
SoloPilot
0

Попробуйте это для простого решения

cmd & выход

Охотник Фрейзер
источник