Node.js / Express和并行队列

时间:2014-02-28 22:34:46

标签: node.js concurrency express queue

我们正在构建一个基础架构,其中包含Node.js服务器和Express。

在服务器中,发生的事情如下:

  1. 服务器接受来自客户端的传入HTTP请求。
  2. 服务器生成两个文件(此操作可以“相对较长”,也意味着0.1秒左右)
  3. 服务器将生成的文件(每个约20-200 KB)上传到外部CDN
  4. 服务器响应客户端,这包括CDN上文件的URI
  5. 目前,服务器按顺序为每个请求执行此操作,这非常有效(Node / Express可以自动处理并发请求)。但是,随着我们计划增长,并发请求的数量可能会增加,我们认为实现队列处理请求会更好。否则,我们可能会面临同时运行太多任务以及与CDN打开过多连接的风险。快速回复客户并不是一件相关的事情。

    我在想的是在Node服务器中有一个单独的部分,其中包含一些“worker”(2-3,但我们会进行测试以确定正确的同时操作数) )。 因此,新流程看起来像:

    1. 在接受来自客户端的请求后,服务器会向队列添加操作。
    2. 有2-3名(待测试)工作人员从队列中取出元素并执行所有操作(生成文件并将其上传到CDN)。
    3. 当工作人员处理完操作时(如果它在队列中停留相对较长时间无关紧要),它会通知节点服务器(回调),服务器响应客户端(已经等待)同时)。
    4. 您如何看待这种方法?你认为这是正确的吗?

      最重要的是,如何在Node / Express中实现?

      感谢您的时间

4 个答案:

答案 0 :(得分:27)

tldr; 您可以使用本机Node.js cluster module来处理大量并发请求。

有些序言: Node.js本身就是单线程。其Event Loop即使在单线程模型中也能同时处理多个请求,这是IMO的最佳功能之一。

真正的交易: 那么,我们如何扩展它以处理更多并发连接并使用所有可用的CPU?使用cluster module

该模块将完全按照@Qualcuno的指示工作,这将允许您在主服务器后面创建多个工作程序(也称为进程)以共享负载并更有效地使用可用的CPU。

根据Node.js官方文档:

  

因为工人都是独立的过程,所以他们可能会被杀死   根据您的计划需求重新生成,而不会影响其他人   工作人员。只要有一些工人还活着,服务器   将继续接受联系。

必填示例:

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

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

  cluster.on('exit', function(worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
} else {
  // Workers can share any TCP connection
  // In this case its a HTTP server
  http.createServer(function(req, res) {
    res.writeHead(200);
    res.end("hello world\n");
  }).listen(8000);
}

希望这就是你所需要的。

如果您有任何其他问题,请评论。

答案 1 :(得分:5)

(回答我自己的问题)

根据this question on Stack Overflow,我的解决方案是使用Caolan McMahon's async module实现队列。

主应用程序将创建作业并将其推入队列,该队列可以运行的并发作业数量有限制。这允许同时处理任务,但严格控制限制。它在Mac OSX上就像Cocoa的NSOperationQueue一样。

答案 2 :(得分:1)

为此,我将使用Heroku为Web / Worker Dynos(服务器)提供的结构。 Web服务器可以接受请求并将信息传递给可以进行信息处理和上载的工作人员。我希望前端站点在套接字(socket.io)上侦听外部CDN的url,当上传完成时,将从工作人员触发。希望这是有道理的。

答案 3 :(得分:0)

您可以将Kue模块与Redis一起使用(数据库来保存作业)支持队列。 你创建工作并将它们放在一个使用kue模块中,你可以让有多少工人在他们身上工作。 有用的链接: kue - https://github.com/Automattic/kue