Nodejs connect EMFILE — Как повторно использовать соединения?

Я реализую сценарии на основе NodeJS для связи с кушеткой и другой службой. Это длинный сценарий, и через некоторое время я получаю «подключить EMFILE» для службы. Мой пример кода приведен ниже:

function createContainer(chunkName,recordingID,chunkData)
{
  var swiftHTTPPath='http://'+swiftIPAddr+'/swift/v1/'+recordingID;
  var path = '/swift/v1/'+recordingID;
  var swiftOptions = {
    hostname : swiftIPAddr,
    port     : swiftPort,
    path     : path,
    method   : 'PUT',
  };

  http.get(swiftHTTPPath, function(res) {
    if(res.statusCode == '404')
    {
      var req = http.request(swiftOptions, function(res)
      {
        res.setEncoding('utf8');
        res.on('data', function (chunk)
        {
          console.log('Container created');
        });
        res.on('end', function() {
        });
      });
      req.on('error', function(e)
      {
        console.log(e.message);
      });
      req.end();
    }
    else
    {
      console.log('Container already exists');
    }
  }).on('error', function(e)
  {
    console.log('e.message);
  });
}

Следующая команда показывает, что открыто более 1024 соединений.

lsof -i -n -P > mylog.log

........
node    14135 ubuntu 1020u  IPv4 5249347      0t0  TCP 10.1.1.1:53623->10.1.1.2:8091 (ESTABLISHED)
node    14135 ubuntu 1021u  IPv4 5249350      0t0  TCP 10.1.1.1:42021->10.1.1.2:11210 (ESTABLISHED)
node    14135 ubuntu 1022u  IPv4 5249351      0t0  TCP 10.1.1.1:53627->10.1.1.2:8091 (ESTABLISHED)
........

Я могу увеличить значения ulimit, но я хотел бы знать, правильно ли я выполняю запрос HTTP GET, POST. Есть ли способ повторно использовать/разорвать соединение?


person KarthikJ    schedule 03.09.2015    source источник


Ответы (1)


Поскольку похоже, что все (или большинство) ваших запросов направляются к одному хосту, вы можете установить максимальное количество одновременных сокетов на хост равным ограниченному числу, например 100. Сделайте это с помощью agent.maxSockets в модуле Node http.

Что касается простого повторного использования соединений, это должно происходить автоматически. Тот факт, что это не так, заставляет меня поверить, что вы отправляете много запросов одновременно... поэтому вы также можете решить эту проблему, выдавая запросы более постепенно.

person John Zwinck    schedule 03.09.2015
comment
Спасибо за ваш ответ. К сожалению, я не могу оформить запрос постепенно из-за особенностей системы. Значит ли это, что я выдаю 1024 одновременных запроса (я так подозреваю)? Есть ли что-то, что я мог бы сделать по-другому в своих HTTP-запросах? - person KarthikJ; 03.09.2015
comment
Насколько я понимаю, сокет будет закрыт после завершения запроса (GET, PUT) или, по крайней мере, его следует использовать повторно. Я планирую запускать скрипт 24x7 с подключением к нескольким системам. Как мне справиться с этим сценарием? - person KarthikJ; 03.09.2015
comment
@KarthikJ: Ну, вы можете просто увеличить свой ulimit. - person John Zwinck; 04.09.2015