nodejs多进程,在pm2上执行
发布于 7 年前 作者 binginto 7054 次浏览 来自 问答

为了充分利用多核cpu,采用多进程。而由于需求中,需要用到子进程与主进程之间消息交互处理。故不能使用pm2命令实现多进程,而是采用nodejs中cluster模块实现。 Demo如下

var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
       cluster.fork();
    }

    cluster.on('listening', function (worker, address) {
        console.log('[master] ' + 'listening: worker' + worker.id + ',pid:' + worker.process.pid + ', Address:' + address.address + ":" + address.port);
    });

    Object.keys(cluster.workers).forEach(function(id) {
        cluster.workers[id].on('message', function(msg){
            console.log('[master] ' + 'message ' + msg);
            cluster.workers[id].send('[master] ' + 'hi worker' +process.pid);
        });
    });

} else if (cluster.isWorker) {
	process.send('[worker] worker'+process.pid+' received!');
    process.on('message', function(msg) {
        console.log('[worker] '+msg);
    });

    http.createServer(function (req, res) {
            res.writeHead(200, {"content-type": "text/html"});
            res.end('worker'+cluster.worker.id+',PID:'+process.pid);
    }).listen(3000);
}

使用node运行时候,node demo.js 。正常 untitled2.png

使用pm2运行时候,pm2 start demo.js 。通过pm2 monit 监控,发现日志一直在打印记录,意味着进程会一直发送消息,而不是停止 ![untitled3.png](//dn-cnode.qbox.me/Fl4gXckslWKJBXoTaFYvgwOZQBm

而通过pm2 运行我的实例代码时候,甚至会出现报错 untitled4.png untitled5.png

不知道这是什么原因所导致的,应该怎样处理?我目前是专用forever来执行,但不清楚为什么使用pm2 会导致这个问题,希望知道的朋友给我解疑一下。 谢谢大家。

4 回复

其实pm2是可以实现cluster的 pm2 start socket.js -i 4 假设你要4个子进程 当然如果你之前开启了fork模式,就要先 pm2 delete socket

从你的截图来看,你现在pm2用的是fork模式

pm2 start demo.js -i 4

楼上的根本连楼主想问啥都没看清就急着回答了。。。 其实你出现这个原因也很简单,默认 pm2 会开启 pmx 监控,换句话说,直接 pm2 start xxx.js ,那么 pm2 的主进程会不停向子进程发送一个 {"type":"axm:monitor","data":{"Loop delay":{"value":"2.61ms","agg_type":"avg","alert":{}}}} 类似这样的消息。 而你的代码中,又有这么一段:

Object.keys(cluster.workers).forEach(function (id) {
    cluster.workers[id].on('message', function (msg) {
      console.log('[master] ' + 'message ' + JSON.stringify(msg));
      cluster.workers[id].send('[master] ' + 'hi worker' + process.pid);
    });
  });

很显然,每收到一条 pm2 发送的 pmx 监控数据就会又触发向子进程发送消息,所以你用 pm2 启动会看到日志一直输出。

要解决这个问题也很简单,启动参数带上 --no-pmx 即可:

pm2 start socket.js --no-pmx

@hyj1991 原来是这个原因。了解啦。谢谢你。

回到顶部