我有一个不断请求页面的node.js脚本,有点像cron作业。
然而,几分钟后,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');
答案 0 :(得分:4)
request.on('response', function (response) {
setTimeout(function(){cron(path)},15000);
});
对于每个回复,您都会创建一个新的cron
作业。记录您的回复。如果你从你的请求中得到超过1,那么你的exponantially创建更多的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');
一次,这样就可以放在模块范围内的文件顶部。
{{1}}
答案 1 :(得分:0)
除了来自@Raynos的提示之外,还有另一个提示。我发现在长时间运行的进程中这样的递归调用让我有点紧张,所以我错误地使用setInterval。我可能会拆分cron和http行为,以防你想尝试重新使用那个逻辑,尽管这取决于你的背景:
e.g。在节点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