Node.js / Express应用程序中的集群进程阻塞

时间:2013-11-05 21:00:11

标签: node.js

我正在使用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的建议!

2 个答案:

答案 0 :(得分:0)

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

您应该尝试一些较新的线程选项,从/ slow函数创建一个线程。请参阅http://bjouhier.wordpress.com/2012/03/11/fibers-and-threads-in-node-js-what-for/,具体为https://github.com/xk/node-threads-a-gogo

Threads-a-gogo有一个与你https://github.com/xk/node-threads-a-gogo/blob/master/examples/demo.js密切匹配的例子。

答案 1 :(得分:0)

如果你有几个CPU核心集群应该运行几个进程。 它很好地解释了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);
}