如何重启一个Node.js子进程

4

我正在尝试重新启动一个名为serverSpawnProcesschild_process。虽然我可以停止它,但是我无法再次启动它。

serverSpawnProcess.stdin.write('stop\n');
serverSpawnProcess = null;
setTimeout(function() {
  serverSpawnProcess = spawn('java', [
    '-Xmx512M',
    '-Xms512M',
    '-jar',
    'server_files/minecraft_server.jar',
    'nogui'
  ]);
  response.send('r');
}, 10000);

这是我认为的做法,但它只会停止服务器,而不会再次生成。 如果有帮助的话,Node.js版本号为5.3.0。

编辑 为了其他人的参考,我最终将 spawn 放入一个函数中,并像这样调用该函数。
serverSpawnProcess.on("close", function() {
    response.send('r2');
    // Wait for process to exit, then run again

    startServer();
 });

你有没有查看新生成进程的error事件?它显示了什么? - Ross
4个回答

3

我完成这个目标的方式是这样的。假设我有一个camCmd,它允许我将单反相机用作网络摄像头,但它会定期崩溃。目标是在不中断流的情况下自动重新启动它。下面的代码正好实现了这一点。

const { spawn } = require('child_process')

const camCmd = `gphoto2 --stdout --capture-movie | \
  ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p \
  -loglevel error -f v4l2 /dev/video1`

const respawn = spawned => {
  spawned.on('close', () => {
    respawn(spawn(camCmd, { shell: true }))
  })
}
respawn(spawn(camCmd, { shell: true }))

简单来说它是一个递归函数,其参数为你要生成的任何内容。一旦关闭,它会使用新生成的参数再次调用自身。


1
我的猜测是,当你的Minecraft服务器超时10秒后仍在运行(根据文档,它会将一些数据保存到磁盘上),当你尝试运行另一个实例时,由于端口仍在使用中而失败。
请按照以下方式尝试:
serverSpawnProcess.stdin.write('stop\n');
serverSpawnProcess.on("close", function() {
    // Wait for process to exit, then run again

    serverSpawnProcess = spawn('java', [
        '-Xmx512M',
        '-Xms512M',
        '-jar',
        'server_files/minecraft_server.jar',
        'nogui'
    ]);
});

同样,正如https://stackoverflow.com/users/1139700/ross所建议的那样,添加一个错误事件监听器,以便您确切地了解问题所在。

serverSpawnProcess.on("error", function(err) {
    // ugh, something went wrong
    console.log("Server error:", err);
});

0

您是在什么情况下尝试重新启动它?在错误发生时还是在特定条件下?如果是前者,请查看:http://schier.co/blog/2013/01/06/restarting-workers-in-a-nodejs-cluster.html

我能够通过将我的服务器嵌套在以下方法中来自动重新启动错误,这是从上面链接修改而来的:

var cluster = require('cluster');

if (cluster.isMaster) {
    cluster.fork();

    cluster.on('exit', function(deadWorker, code, signal) {
        // Restart the worker
        var worker = cluster.fork();

        // Note the process IDs
        var newPID = worker.process.pid;
        var oldPID = deadWorker.process.pid;

        // Log the event
        console.log('worker '+oldPID+' died.');
        console.log('worker '+newPID+' born.');
    });
} else {
  // server code is initialized here
}

我正在尝试在调用Express的get请求到/restartserver时重新启动它,但我会记住这个答案以备将来实现。 - gmemstr

0
  var serverSpawnProcess = spawn('java', [
    '-Xmx512M',
    '-Xms512M',
    '-jar',
    'server_files/minecraft_server.jar',
    'nogui'
  ]);

serverSpawnProcess.on('exit', function (code)
{
    console.log("exit here with code: ", code);
});
serverSpawnProcess.stdout.on('data', function (data) {
    console.log('stdout: ' + data);
});

serverSpawnProcess.stderr.on('data', function (data) {
    console.log('stderr: ' + data);
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接