我有一个简单的案例,我从我的 node.js 服务器请求不同的上游代理服务器。随着负载的增加,我看到请求需要花费大量时间来执行(尽管从我的上游代理服务器响应所花费的时间在请求中是恒定的)。为了演示这个问题,我编写了一个示例程序,如下所示。当我执行下面的程序时,第一个请求需要118 毫秒才能执行,最后一个请求需要10970 毫秒, 具体取决于您点击的网站(我已将 url 更改为 google,请在您喜欢的网站上试用)。如果您观察到我正在使用异步来并行化我的请求。
问题是,node.js 在并行运行时需要这么多时间来执行请求的原因是什么。为了提供更多有关基础设施设置(centos 6.5)的上下文,我打开了从 1024 到 65535 的端口范围,将 fin_timeout 更改为 15 秒并在 sysctl.conf 中为套接字启用 tw_reuse =1
var http = require('http');
var uuid = require('node-uuid');
var async = require('async');
function callExternalUrl(){
var uniqueId = uuid.v4();
console.time(uniqueId);
var options = {
host: 'google.com',
port: '80',
path: '/',
method: 'GET'
};
var req = http.request(options, function(res) {
var msg = '';
res.setEncoding('utf8');
res.on('data', function(chunk) {
msg += chunk;
console.timeEnd(uniqueId);
});
res.on('end', function() {
});
});
req.end();
}
function iterateAsync(callback){
var iter = [];
for(var i=0; i<1000; i++){
iter[i] = i;
}
async.each(iter,
function(item, callback) {
callExternalUrl();
},
function(err) {
callback(err);
}
);
}
iterateAsync(function(){console.log('done');});
下面给出更多的上下文是 ruby 中的代码来做同样的事情。我知道我不能像苹果和苹果那样比较这两种语言。但这个想法是显示使用 ruby 依次执行相同请求所需的时间。我没有看到按顺序发出的每个请求的响应时间有任何增加。所以,我怀疑使用节点的并行请求需要更多时间来响应请求(问题不是来自服务器响应,而是来自机器本身发送请求)
require 'rest_client'
1000.times do |number|
beginning = Time.now
response = RestClient.get 'http://google.com'
puts "Time elapsed #{Time.now - beginning} seconds"
end