AWS Lambda上的NodeJS群集

时间:2017-04-04 16:52:57

标签: node.js aws-lambda

是否可以在lambda函数中使用集群模块?我试过这个:

'use strict';
var cluster = require('cluster');  
var http    = require('http');  
var os      = require('os');

var numCPUs = os.cpus().length;
console.log('Number of Cores : ', numCPUs);

exports.test = (event, context, callback) => {
    if (cluster.isMaster) {
        for (var i = 0; i < numCPUs; ++i) {
            cluster.fork();
        }
    } else {
        console.log('child process ');
    }
}

核心数总是2,但我从未看到子进程日志。

评论示例更新:

我尝试实施消息模式,但我还没有收到孩子们发送的消息。 for循环正确地遍历集群工作者,但从未找到消息。

'use strict';
var cluster = require('cluster');  
var http    = require('http');  
var os      = require('os');

var numCPUs = os.cpus().length;
console.log('Number of Cores : ', numCPUs);

exports.test = (event, context, callback) => {
    if (cluster.isMaster) {
        for (var i = 0; i < numCPUs; ++i) {
            cluster.fork();
        }
        for (const id in cluster.workers) {
            cluster.workers[id].on('message', messageHandler);
        }
    } else {
        process.send('running');
    }
};

function messageHandler(msg) {
    console.log(msg);
}

2 个答案:

答案 0 :(得分:2)

您的代码看起来是正确的,除非您假设在主进程的控制台上可以看到来自工作程序的console.log()调用。情况并非总是如此,因为调用不会在进程树中传播。

在致电fork()后,请将此代码段丢入以接收来自子流程的消息:

for (var id in cluster.workers) {
  cluster.workers[id].on('message',function () {
    console.log('got message from ' + id + ': ' + msg);
  });
}

然后在你的第二个if / else案例中(存储了工人流程的处理),将其添加到主人的消息中:

process.send('running');

你也可以通过process.send()发送对象(最好),我只是用String作为例子。有关官方文档的更详细信息:Cluster - How it works

答案 1 :(得分:2)

问题似乎是没有为每个子进程调用exports.test函数。 cluster.fork()调用具有从头开始的不同参数的文件的新实例,与 C 中的fork()系统调用不同,后者克隆当前进程并从其继续在父母和子女的过程中都行。

对于父进程,AWS lambda将调用此函数,但子进程只定义该函数,然后等待。

我翻转你的逻辑,以便cluster.isMaster检查发生在其他一切周围;我在本地测试了以下内容:

'use strict';
let cluster = require('cluster')
let http = require('http')
let os = require('os')

let numCPUs = os.cpus().length

if (cluster.isMaster) {
  console.log('Number of Cores : ', numCPUs);
  exports.test = (event, context, callback) => {
    for (let i = 0; i < numCPUs; ++i) {
      cluster.fork();
    }
    for (const id in cluster.workers) {
      cluster.workers[id].on('message', messageHandler);
    }
  }
} else {
  process.send('running');
}

function messageHandler(msg) {
  console.log(msg);
}

// The following used for local test

exports.test && exports.test();