Node.js http请求内存和cpu猪
问题描述:
我有一个node.js脚本不断地请求页面,有点像cron作业。Node.js http请求内存和cpu猪
但是,几分钟后,Node开始使用大量的CPU(高达70%)和内存(高达200MB)。
我的脚本有什么问题?
function cron(path)
{
var http = require('http');
var site = http.createClient(443, 'www.website.com', true);
var request = site.request('GET', path, {'host': 'www.website.com'});
request.end();
request.on('response', function (response) {
setTimeout(function(){cron(path)},15000);
});
}
cron('/path/to/page');
答
request.on('response', function (response) {
setTimeout(function(){cron(path)},15000);
});
对于每一个响应创建一个新的cron
工作。记录你的回应。如果你从你的请求中获得更多的1,那么你指数地创建更多的cron作业。
您创建一个function() {}
并参照path
。因此整个范围状态都保持不变。你想加入这个以释放内存:
var site = null;
var request = null;
你在模块范围调用require("http")
在函数内部而不是外部。您只需要获取http
一次,以便在模块范围内放置在文件顶部。
var http = require('http');
var site = http.createClient(443, 'www.website.com', true);
function cron(path)
{
var request = site.request('GET', path, {'host': 'www.website.com'});
request.end();
var once = true;
request.on('response', doIt);
function doIt(response) {
if (!once) {
once = null;
doIt = function() {};
setTimeout(function(){cron(path)},15000);
}
});
site = null;
request = null;
}
cron('/path/to/page');
答
除了来自@Raynos的提示之外,还有另外一个。我发现在长时间运行的过程中,像这样的递归调用让我有点紧张,所以我会错误地使用setInterval来代替。如果您想尝试重新使用该逻辑,我可能会拆分cron和http行为,但这将取决于您的上下文:
例如,在节点0.4.7中:
var https = require('https');
function poll(path)
{
https.get({
host: 'www.website.com',
port: 443,
path: path
}, function(res) {
console.log("Got response: " + res.statusCode);
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
}
function cron(path)
{
return setInterval(function(){
poll(path);
},15000);
}
var intervalId = cron('/path/to/page'); // keep in case you need to use clearInterval
太好了,我正在测试新的脚本。我不明白为什么在request.on()回调中使用“once”变量,每个请求只能有一个响应? – koen 2011-04-15 13:26:16
@koen以确保它只被调用一次。您是否想在获得_a_响应时创建新的'cron'作业,或者是否希望为从请求中获得的_every_响应创建新的'cron'作业?请注意,我的一些“优化”可能由V8解释器为您完成。我不知道V8是否知道什么时候释放内存,当不需要时将变量设置为'null'基本上标记该内存以供GC清除。 – Raynos 2011-04-15 13:28:19
我想在旧请求完成时创建一个新的响应。有时候,页面加载需要更长的时间,我只需要一个cron,这就是为什么我使用request.on()回调。我只是检查并且页面只返回一个响应。 – koen 2011-04-15 13:36:09