Linux

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

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

$ node server.js &

 Однако через 2,5 часа терминал становится неактивным, и процесс завершается. Могу ли я как-то сохранить процесс даже при отключенном терминале? Я пробовал использовать nohup, но, как только я закрываю терминал SSH или отключаю интернет, процесс сервера сразу же останавливается. Я знаю, что существует модуль node.js, forever. Он запускает сервер node.js в качестве службы демона. Как мне обойти данное ограничение?

 

Ответ 1

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

nohup node server.js &

Существует также команда «jobs» для просмотра индексированного списка этих фоновых процессов. И вы можете завершить фоновый процесс, выполнив kill %1 или kill %2, где номер — это индекс процесса. Супер решение (позволяет повторно подключиться к процессу, если он интерактивный):

screen

Затем вы можете отсоединить его, нажав Ctrl+a+d, а затем присоединить обратно, выполнив команду screen -r. Также рассмотрите более новую альтернативу screen — tmux.

 

Ответ 2

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

Запуск сеанса «screen»:

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 список записей.

 

Ответ 3

 

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

# базовое применение

$ npm install pm2 -g

$ pm2 start server.js

# вы даже можете определить, сколько процессов вы имеете в режиме кластера:

$ pm2 start server.js -i 4

# вы можете запускать различные процессы со сложными настройками запуска

# используя файл ecosystem.json (с переменными env, пользовательскими args и т.д.):

$ pm2 start ecosystem.json

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

$ pm2 startup [platform]

Решение работает для следующих платформ ubuntu|centos|redhat|gentoo|systemd|darwin|amazon.

Начальные скрипты:

Я не буду вдаваться в подробности о том, как написать init-скрипт, потому что я не эксперт в этой теме и это было бы слишком длинно для данного ответа, но в основном это простые shell-скрипты, запускаемые событиями ОС. Пример: 

Docker:

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

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

# создание директории приложения

RUN mkdir -p /usr/src/app

WORKDIR /usr/src/app

# установка зависимостей приложения

COPY package.json /usr/src/app/

RUN npm install

# источник приложения

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



Ответ 4

Запуск команды как системной службы на 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 подменяет исполняемый файл, поэтому служба не останавливается должным образом.

Схожие статьи

Linux

Стоит ли блокировать ICMP?

Linux

Как завершить дочерний процесс по истечении заданного времени ожидания в Bash

Linux

Команда df в Linux не показывает правильное свободное пространство после удаления файла

Linux

Как сделать переадресацию портов с одного IP на другой в одной и той же сети?