节点js从外部请求达到内存限制

时间:2016-04-01 14:28:28

标签: node.js request heap-memory

我正在尝试构建实时信息中心的服务器上运行以下代码。我从API源中提取数据,我需要每隔一段时间将其发布到客户端。现在我试图找出我的服务器可以处理的内容,并且我发现在运行此代码大约20分钟后,服务器速度变慢并崩溃而不显示错误消息。我怀疑它是因为我不断发出越来越多的异步请求(每5秒钟300次),并且在之前的请求能够解决之前堆积了更多请求,从而占用了内存。 / p>

var request = require('request');

var async = require('async');
var db = require('./db.js');
var _ = require('underscore');

var urls = [...]; // List of ~300 urls, 

var interval = setInterval(runRequests, 5000);

function runRequests() {
    var requests = [];

    async.waterfall([
        function(callback) {
            var query = 'select apitoken from apidata where id = 1';
            db.query(query, function(err, rows, fields) {
                if (err) {
                    return callback(err);
                }
                if (rows) {
                    return callback(null, rows[0]['apitoken'];
                }
             });
         },
         function(token, callback) {
             _.each(urls, function(url) {
                 var req = request({
                     url: url,
                     method: "GET",
                     headers: {
                         authorization: token
                     }
                  }, function(err, res, body) {
                     var json = parseJsonSafely(body);

                     if(json) {
                          // Emitting logic
                     }
                     // If the token has expired, shutdown the rest of the
                     // ongoing request that are bound to fail
                     else if(body === 'Request is not authenticated.') {
                         _.each(requests, openRequest) {
                             openRequest.abort();
                         });
                         requests = [];

                         // ... code to refresh the api token
                     }
                  });

                  requests.push(req);
             });

             return calbackk(null);
         }
   ]);
}

function parseJsonSafely(json) {
    var parsedString;

    try {
        parsedString = JSON.parse(json);
    } catch(err) {
        console.log('ERROR: JSON parsing failed. Input: ', json);
    }

    return parsedString;
}

当代码实际投入生产时,我只需要在大约每分钟而不是每5秒运行一次请求,但我目前正试图弄清楚会发生什么我必须访问的网址数量增长。

我是否可以采取任何措施防止代码占用太多内存?我想到的一个选择是为每个请求添加一个超时,以便它自动过期,但我不认为如果请求仍在等待另一轮请求时,这会产生影响。请求已启动。我能做的另一件事是建立一个连接每个的哈希 请求对象到其对应的url。然后,当启动对同一URL的新一轮请求时,如果尚未完成,我可以忽略对特定URL的请求,并且只有在完成后才发出新请求:

var hash = {};
var urls = [...];
_.each(urls, function(url) {
    if (!hash[url]) {
        hash[url] = result(..., function(err, res, body) {
            delete hash[url];
        });
    }
});

这样做的好处是我不认为请求对象会被复制,所以我不得不担心服务器的内存被吃掉了。

如果有人对如何解决这个问题有任何建议,我会很感激。

0 个答案:

没有答案