如何从内部(以编程方式)重新启动Node.js应用程序?

时间:2012-02-20 07:49:47

标签: node.js

如何创建可以自行重启的应用?我想创建一个应用程序,设置一个可以重新启动的Web管理员。这可能吗?如果是这样,怎么样?我认为使用内置于节点的process全局变量可以实现这一点。

7 个答案:

答案 0 :(得分:12)

我已经多次运行Forever并且很容易上手。请查看:https://github.com/nodejitsu/forever

答案 1 :(得分:10)

LK"我

没有外部依赖关系是可能的:

console.log("This is pid " + process.pid);
setTimeout(function () {
    process.on("exit", function () {
        require("child_process").spawn(process.argv.shift(), process.argv, {
            cwd: process.cwd(),
            detached : true,
            stdio: "inherit"
        });
    });
    process.exit();
}, 5000);

来源:https://gist.github.com/silverwind/d0802f7a919ae86ff25e

答案 2 :(得分:8)

我知道回复有点迟,但我有类似的要求。每当我进行配置更改时,我都想重新启动节点进程。我正在使用pm2来管理我的节点进程,结果证明它非常简单。

进行配置更改后,我从节点进程中执行process.exit()。据我所知,进程退出然后pm2重新启动进程。

目前还不确定是否有任何副作用但现在似乎对我有效。

答案 3 :(得分:2)

  1. 您可以使用子进程运行您的应用并根据需要进行操作: https://nodejs.org/api/child_process.html

  2. 永远使用,pm2或者死后重启的任何东西,并使用process.exit()https://nodejs.org/api/process.html

  3. 自杀

答案 4 :(得分:0)

是的,upstart会在没有nodemon的情况下重启您的流程。

npm install -g nodemon
sudo nodemon server.js

nodemon将会查看nodemon已启动的目录中的文件,如果这些文件发生更改,它将自动重新启动您的节点应用程序。

答案 5 :(得分:0)

您可以使用spawn创建一个子进程来有效地复制重启:

  • 模仿当前正在运行的进程的命令行参数,
  • 连接到其父级的当前process.stdin / process.stdout / process.stderr为其自身的流输入/输出(从技术上讲,我认为它与父级“共享”流,但是这里父母立即退出),
  • 不再依赖父进程(使用detached
  • 告诉父进程不要等待父进程退出(使用unref()),然后
  • 退出父进程。
const { spawn } = require('child_process')

const restartProcess = () => {
  spawn(process.argv[1], process.argv.slice(2), {
    detached: true, 
    stdio: ['inherit']
  }).unref()
  process.exit()
}

来源:GitHub user @rockyjvec

答案 6 :(得分:0)

我将它添加到 Linux 的 systemd,它在 network.target 上启动,将控制台记录到 /var/logs/<app>.log 并在失败时重新启动。因此,您可以在其上强制使用 process.exit

sudo touch /lib/systemd/system/<app>.service
sudo tee -a /lib/systemd/system/<app>.service > /dev/null <<EOT
[Unit]
Description=<app>
After=network.target
[Service]
Type=simple
User=$USER
ExecStart=/bin/node --prefix /home/$USER/path/to/app
Restart=on-failure # or always
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=<app>
[Install]
WantedBy=multi-user.target
EOT

sudo touch /etc/rsyslog.d/<app>.conf
sudo tee -a /etc/rsyslog.d/<app>.conf > /dev/null <<EOT
if $programname == '<app>' then /var/log/<app>.log
& stop
EOT

sudo systemctl enable <app>
sudo systemctl daemon-reload
sudo systemctl restart rsyslog
sudo systemctl start <app>