Я подключаюсь к серверу 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