我们正在构建一个具有 Node.js 服务器和 Express 的基础架构。
在服务器中,发生的情况如下:
- 服务器接受来自客户端的传入 HTTP 请求。
- 服务器生成两个文件(这个操作可以“比较长”,也就是0.1秒左右)
- 服务器将生成的文件(每个约 20-200 KB)上传到外部 CDN
- 服务器响应客户端,其中包括 CDN 上文件的 URI
目前服务器对每个请求都按顺序执行此操作,并且效果很好(Node/Express 可以自动处理并发请求)。但是,随着我们计划的增长,并发请求的数量可能会越来越高,我们认为实现一个队列来处理请求会更好。否则,我们可能会面临同时运行的任务过多以及与 CDN 的打开连接过多的风险。快速响应客户无关紧要。
我的想法是在 Node 服务器中设置一个单独的部分,其中包含 几个“worker”(2-3 个,但我们将进行测试以确定同时操作的正确数量)。 因此,新流程看起来像:
- 服务器接受客户端的请求后,将操作添加到队列中。
- 有 2-3 个(待测试)工作人员从队列中取出元素并执行所有操作(生成文件并将它们上传到 CDN)。
- 当worker处理完操作(在队列中停留的时间比较长也没关系),通知Node服务器(回调),服务器响应客户端(一直在等待同时)。
您如何看待这种方法?你认为它是正确的吗?
最重要的是,这如何在 Node/Express 中实现?
感谢您的宝贵时间
最佳答案
tldr; 可以使用原生 Node.js cluster module处理大量并发请求。
一些序言: Node.js 本身是单线程的。其Event Loop即使在单线程模型中,它也非常适契约(Contract)时处理多个请求,这是 IMO 的最佳功能之一。
真正的交易: 那么,我们如何扩展它以处理更多的并发连接并使用所有可用的 CPU?与 cluster module .
这个模块将完全按照@Qualcuno 所指出的那样工作,这将允许您在主服务器后面创建多个工作人员(又名进程)来分担负载并更有效地使用可用的 CPU。
根据Node.js官方文档:
Because workers are all separate processes, they can be killed or re-spawned depending on your program's needs, without affecting other workers. As long as there are some workers still alive, the server will continue to accept connections.
必填示例:
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);
}
希望这是你需要的。
如果您有任何其他问题,请发表评论。
关于Node.js/Express 和并行队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22107144/