长时间运行Node.js服务以持续发出http请求

时间:2015-11-07 03:40:33

标签: node.js

我开始研究我的第一个Node.js应用程序并遇到内存泄漏问题,我无法确定。我希望应用程序以持续运行和轮询和端点的方式充当服务。我想我可能会在这里遗漏一些东西。该项目的想法是让一个节点应用程序不断向我连接到我的网络的Arduino板发出http请求,并在其上安装Web服务器。联网板通过一些JSON或XML来响应请求,这些JSON或XML表示连接到它的传感器的状态。节点应用程序的想法是记录然后发出传感器更改,最终将被另一个电子项目消耗。

节点应用程序目前分为几个模块:

代理 :对arduino网络服务器上的不同端点进行http调用:

var http = require('http'), 
    KeepAliveAgent = require('keep-alive-agent');

var controllerRequestOpts = {};  

function send(path, cb){
  var response = '';

  //build the request
  var request = controllerRequestOpts;      
  request.path = path;

  //make the call to the controller
  http.get(request, function(res){
    res.on('data', function(chunk){
        response += chunk;              
    });
    res.on('end', function(){                           
        cb(null, response);
    });     
  })
  .on('error',function(e){          
    cb(e, null);
  });
}

module.exports = function(controllerOptions){

  controllerOptions.port = controllerOptions.port || 2222;  

  controllerRequestOpts = controllerOptions;
  controllerRequestOpts.agent = new KeepAliveAgent();

  return{
    //JSON
    queryJson: function(cb){        
      send('/json', cb);
    },      
    //XML
    queryXml: function(cb){     
      send('/xml', cb);
    }
    //Additional endpoints
  }
}

runner :使用提供的间隔永久循环,使代理调用arduino

var proxy = require('proxy');
var Watcher = require('./watcher');

var timer;
var toUpdate; 

function initProxy(controllerParams){
  proxy = proxy(controllerParams);
  Watcher = new Watcher();
}

function startListening(startOptions){
  var query;
  //determine the query and callback functions based off configuration
  query = startOptions.queryType === 'json'
    ? proxy.queryJson
    : proxy.queryXml;
  toUpdate = startOptions.queryType === 'json'
    ? Watcher.updateLatestJson
    : Watcher.updateLatestXml;

  //Start running and making requests every 15 seconds
  timer = setInterval(function(){        
    query(handleResponse);
  },startOptions.queryInterval);
}

function handleResponse(err, resp){
  if(err){
    console.log('ERROR: ' + err);
  }
  else{
    toUpdate.call(Watcher, resp);
  }
}

function stopListening(){
  clearInterval(timer);
  process.exit();
}

var runner = {
  connect: function(controllerParams){
    initProxy(controllerParams);
  },
  start: function(startOptions){        
    startListening(startOptions);
    return Watcher;
  },
  stop: function(){
    stopListening();
  }
};

module.exports = runner; 

我有一个“Watcher”模块,它只是一个构造函数,可以将更改发送回调用应用程序,如下所示:

var runner = require('./index');

var controllerSettings = {
  hostname: '192.168.1.150',    
  port:2222
}

var startOptions = {
  queryType: 'json',
  queryInterval: 15000
}

runner.connect(controllerSettings);
var watcher = runner.start(startOptions);
watcher.on('P1Changed', printParams)

一切都按预期工作,但随着应用程序的运行,节点进程的内存使用量不断增加。我想知道我是否错误地使用了http模块,或者如果跑步者不应该使用setInterval。有没有一种标准方法可以将这种应用程序作为“服务”运行,而不是像“服务器”那样运行

1 个答案:

答案 0 :(得分:0)

连续发送多个HTTP请求将导致节点创建巨大的TLSWrap对象,GC将无法在几分钟内清除。

如果您希望一遍又一遍地向同一主机发送数据,则需要打开TCP连接(流),而不是使用具有巨大开销的HTTP请求。