1

我正在使用 Express 框架开发 Node.js 应用程序,并使用集群来处理负载。在测试中,我注意到如果由于某种原因其中一个进程需要很长时间才能加载,它也会影响其他后续请求。我为此做了一个简单的测试用例:

https://gist.github.com/anonymous/7325816

使用“node app.js”运行示例并尝试http://localhost:8080/slow在一个浏览器窗口中加载(阻塞计算需要几秒钟)并http://localhost:8080/fast立即在另一个窗口中加载,后者也需要几秒钟才能加载。

如果我理解正确,这是因为运行计算的同一进程正在尝试处理新请求:但是如何避免这种情况呢?

编辑:

这是运行 /slow 后运行 Siege 的 HTTP 请求的输出:

HTTP/1.1 200   0.01 secs:      89 bytes ==> GET  /fast
HTTP/1.1 200   6.32 secs:      89 bytes ==> GET  /fast
HTTP/1.1 200   0.01 secs:      89 bytes ==> GET  /fast
HTTP/1.1 200   6.84 secs:      89 bytes ==> GET  /fast
HTTP/1.1 200   0.00 secs:      89 bytes ==> GET  /fast
HTTP/1.1 200   7.41 secs:      89 bytes ==> GET  /fast
HTTP/1.1 200   0.00 secs:      89 bytes ==> GET  /fast
HTTP/1.1 200   9.04 secs:      89 bytes ==> GET  /fast

编辑2:

问题在于在 OSX 上运行的 Node.js 的最新 Git 版本(v0.11.9-pre):运行当前版本 v0.10.21 它可以正常工作,而无需将请求传输到被阻止的进程。感谢@goten 的建议!

4

2 回答 2

0

node.js 本质上是单线程的。它使用回调,但每个回调都在单个事件循环上运行。因此,无论您如何配置回调,最终您都会遇到 /slow 必须运行的情况,并且会排挤其他所有内容,直到完成。这是因为 /slow 是 CPU 密集型的。如果它有一些 IO,那么该 IO 可以异步完成。

There are a few newer threading options that you should try, creating a thread from the /slow function. See http://bjouhier.wordpress.com/2012/03/11/fibers-and-threads-in-node-js-what-for/, specifically https://github.com/xk/node-threads-a-gogo.

Threads-a-gogo has an example that closely matches yours at https://github.com/xk/node-threads-a-gogo/blob/master/examples/demo.js.

于 2013-11-05T21:41:06.863 回答
0

If you have several CPU cores cluster should run several process. It's pretty well explain there http://rowanmanning.com/posts/node-cluster-and-express/

var http = require('http');
var cluster = require('cluster');
var express = require('express');

if(cluster.isMaster){
    //count the CPU
    var cpuCount = require('os').cpus().length;

    // Create a worker for each CPU
    for (var i = 0; i < cpuCount; i += 1) {
        cluster.fork();
    }
}
else{
    var app = express();
    var server = http.createServer(app);

    app.get('/slow', function(req, res){
        someSlowFunction();
    });
    app.get('/fast', function(req, res){
        someFasterFunction();
    });

    server.listen(3000);
}
于 2013-11-06T01:32:34.483 回答