我正在使用node.js构建一个系统,用户可以在该系统中从Web界面生成工作进程,而在将这两个条件组合到系统时遇到了麻烦:

  • Web服务器进程和工作进程应该独立运行,这样,如果Web服务器崩溃,工作进程就不会受到影响。
  • 母进程应该能够从工作进程中接收至少一条初始消息。该消息之后,我想将工作进程的输出记录到文件中。

  • 我已经能够自己完成两个标准,但不能一起完成。这是我代码的相关部分当前的样子:
    function spawnWorker (id, callback) {
        var worker = spawn("node", [require.resolve("worker"), id], {
            detached: true,
            stdio: ["ignore", "pipe", "pipe"]
        });
    
        worker.unref();
    
        var logfile = fs.createWriteStream("foo.log");
    
        worker.stdout.once("data", function (data) {
            worker.stdout.pipe(logfile);
            worker.stderr.pipe(logfile);
    
            callback(undefined, data.toString());
        });
    }
    

    这符合条件2(即,它接收到来自工作程序的第一条消息,并将所有后续输出重定向到文件),但是,如果我杀死了母进程,那么即使输出已经重定向,工作程序进程也会被杀死。

    我的猜测是,这是因为在将工作程序的stdout和stderr发送到文件流之前,已将它们通过管道传输到母进程。如果我在生成进程时传递流,那么根据docs,节点将在工作进程中复制该流:



    收到第一条消息后,有什么方法可以删除母进程和工作进程之间的连接吗?还是我应该使用某种类型的RPC来完成此操作,如果是这样,那么一旦进行通信,此一条消息的最佳选择是什么?

    最佳答案

    我使用节点的 net 模块解决了此问题,在随机端口上生成服务器,该服务器在启动时会传递给工作程序(因此,服务器知道准备就绪时将响应发送到哪里)。

    下面是我的解决方案实现的示例,以澄清,它满足以下要求:

  • 保存工作进程的日志输出
  • 使工作进程与母进程分离(这样,如果后者崩溃,则不会影响工作进程)
  • server.js
    var net = require("net"),
        fs = require("fs"),
        spawn = require("child_process").spawn,
        randomPort = require("get-port");
    
    randomPort(function (port) {
        var server = net.createServer(function (connection) {
            connection.on("data", function (data) {
                server.close();
                /**
                 * Response received from worker, this is where you would put
                 * your logic that returns a response to the client that initiated
                 * the request to the server.
                 */
            });
        });
    
        server.listen(port);
    
        var logfile = fs.createWriteStream("log");
        var worker = spawn("node", ["worker.js", port], {
            detached: true,
            stdio: ["ignore", logfile, logfile]
        });
    
        worker.unref();
    
        worker.on("close", function (status, message) {
            console.log("worker closed", status, message);
        });
    });
    
    worker.js
    var net = require("net");
    
    var options = process.argv.slice(2),
        rpcPort = Number(options[1]);
    
    var client = net.connect({port: rpcPort}, function () {
        client.end(JSON.stringify({started: true}}));
    });
    

    关于javascript - 收到第一条消息后,分离 Node 子进程,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29896474/

    10-14 13:02
    查看更多