496

我通过 putty SSH 连接到 linux 服务器。我尝试将它作为后台进程运行,如下所示:

$ node server.js &

但是,在 2.5 小时后,终端变为非活动状态,进程终止。无论如何,即使终端断开连接,我也可以保持进程活跃?


编辑 1

实际上,我试过nohup了,但只要我关闭 Putty SSH 终端或拔掉我的互联网,服务器进程就会立即停止。

在 Putty 中我有什么需要做的吗?


编辑 2(2012 年 2 月)

有一个node.js模块,永远。它将 node.js 服务器作为守护程序服务运行。

4

14 回答 14

1143

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

  1. nohup意思是:即使stty被切断也不终止这个进程。
  2. > /dev/null表示:stdout 转到 /dev/null(这是一个不记录任何输出的虚拟设备)。
  3. 2>&1意思是:stderr 也转到 stdout(它已经被重定向到/dev/null)。您可以将 &1 替换为文件路径以保留错误日志,例如:2>/tmp/myLog
  4. &最后意味着:将此命令作为后台任务运行。
于 2012-08-08T01:48:56.053 回答
527

简单的解决方案(如果您对返回流程不感兴趣,只希望它继续运行):

nohup node server.js &

还有jobs查看这些后台进程的索引列表的命令。kill %1您可以通过运行或kill %2使用数字作为进程的索引来终止后台进程。

强大的解决方案(如果它是交互式的,则允许您重新连接到进程):

screen

然后,您可以通过按 Ctrl+a+d 分离,然后通过运行附加回来screen -r

还要考虑屏幕的更新替代品 tmux。

于 2011-01-25T17:55:03.147 回答
140

你真的应该尝试使用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 是一个条目列表。

于 2013-06-28T06:40:49.547 回答
132

这是一个老问题,但在谷歌上排名很高。我几乎不敢相信投票最高的答案,因为在屏幕会话中运行 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

永远.jshttps ://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

初始化脚本

我不会详细介绍如何编写初始化脚本,因为我不是这个主题的专家,而且这个答案太长了,但基本上它们是简单的 shell 脚本,由操作系统事件触发。您可以在此处阅读有关此内容的更多信息

码头工人

只需在带有-d选项的 Docker 容器中运行您的服务器,,您就有了一个守护进程的 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

希望这有助于有人登陆此页面。始终使用合适的工具完成工作。它会为您节省很多头痛和几个小时!

于 2016-03-18T18:02:19.140 回答
25

另一个解决方案不承认这份工作

$ nohup node server.js &
[1] 1711
$ disown -h %1
于 2013-04-11T08:39:12.363 回答
15

nohup将允许程序在终端死机后继续运行。实际上,我遇到过nohup阻止 SSH 会话正确终止的情况,因此您也应该重定向输入:

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

根据nohup配置方式,您可能还需要将标准输出和标准错误重定向到文件。

于 2011-01-25T17:56:29.987 回答
8

Nohup 和 screen 为在后台运行 Node.js 提供了很好的轻量级解决方案。Node.js 进程管理器 ( PM2 ) 是一个方便的部署工具。在您的系统上使用 npm 全局安装它:

npm install pm2 -g

将 Node.js 应用程序作为守护进程运行:

pm2 start app.js

您可以选择将其链接到Keymetrics.io一个由 Unitech 制造的监控 SAAS。

于 2015-09-21T18:44:43.333 回答
7

根据@Yoichi 的回答,我的shell rc 文件中有这个函数:

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

你可以这样使用它:

nohup-template "command you would execute here"
于 2014-05-22T19:48:35.640 回答
7
$ disown node server.js &

它将从活动任务列表中删除命令并将命令发送到后台

于 2014-07-30T17:09:01.870 回答
5

你读过nohup命令吗?

于 2011-01-25T17:54:55.493 回答
3

使用 sysv init 在 debian 上将命令作为系统服务运行:

复制骨架脚本并根据您的需要对其进行调整,可能您所要做的就是设置一些变量。/lib/init/init-d-script如果某些内容不符合您的需要,您的脚本将从 继承良好的默认值- 在您的脚本中覆盖它。如果出现问题,您可以在 source 中查看详细信息/lib/init/init-d-script。强制变量是DAEMONNAME。脚本将用于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

这就是我为我的 wikimedia wiki 运行一些 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 替换了可执行文件,所以服务没有正确停止。

于 2017-06-05T07:48:08.790 回答
3

除了上面很酷的解决方案之外,我还提到了 supervisord 和 monit 工具,它们允许启动进程、监视它的存在并在它死亡时启动它。使用“monit”,您还可以运行一些主动检查,例如检查进程是否响应 http 请求

于 2017-11-17T20:21:41.707 回答
3

对于 Ubuntu,我使用这个:

(exec PROG_SH &> /dev/null &)

问候

于 2018-01-18T17:07:01.750 回答
0

试试这个简单的解决方案

cmd & 退出

于 2018-06-12T17:12:48.437 回答