Node.js http请求内存和cpu猪

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'); 
+0

太好了,我正在测试新的脚本。我不明白为什么在request.on()回调中使用“once”变量,每个请求只能有一个响应? – koen 2011-04-15 13:26:16

+0

@koen以确保它只被调用一次。您是否想在获得_a_响应时创建新的'cron'作业,或者是否希望为从请求中获得的_every_响应创建新的'cron'作业?请注意,我的一些“优化”可能由V8解释器为您完成。我不知道V8是否知道什么时候释放内存,当不需要时将变量设置为'null'基本上标记该内存以供GC清除。 – Raynos 2011-04-15 13:28:19

+0

我想在旧请求完成时创建一个新的响应。有时候,页面加载需要更长的时间,我只需要一个cron,这就是为什么我使用request.on()回调。我只是检查并且页面只返回一个响应。 – koen 2011-04-15 13:36:09

除了来自@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