我正在使用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的建议!
答案 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);
}