Подключайте ETIMEDOUT к службе приложений Azure при вызове конечной точки HTTP без указания maxSockets

У меня возникают проблемы с тайм-аутом при многократном вызове конечной точки HTTP[S] из node.js внутри службы приложений Azure.

Здесь мой код для решения проблемы.

const fetch = require('node-fetch');
const https = require("https");
const agent = new https.Agent();

function doWork() {
  const works = [];
  for (let i = 0; i < 50; i++) {
    const wk = fetch('https://www.microsoft.com/robots.txt', { agent })
    .then(res => res.text())
    .then(body => console.log("OK", i))
    .catch((err) => console.log("ERROR", i, err));
    works.push(wk);
  }

  return Promise.all(works);
}

doWork()
.catch((err) => {
  console.log(err);
});

При запуске этого приложения 3 или 4 раза в стандартной средней службе приложений (я запускаю его с помощью Kudu, но обнаруживаю эту ошибку в стандартном веб-приложении), я получаю следующую ошибку для каждого запроса:

{ FetchError: request to https://www.microsoft.com/robots.txt failed, reason: connect ETIMEDOUT 23.206.106.109:443
    at ClientRequest.<anonymous> (D:\home\site\test\test-forge-calls\node_modules\node-fetch\lib\index.js:1393:11)
    at emitOne (events.js:96:13)
    at ClientRequest.emit (events.js:188:7)
    at TLSSocket.socketErrorListener (_http_client.js:310:9)
    at emitOne (events.js:96:13)
    at TLSSocket.emit (events.js:188:7)
    at emitErrorNT (net.js:1276:8)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
  message: 'request to https://www.microsoft.com/robots.txt failed, reason: connect ETIMEDOUT 23.206.106.109:443',
  type: 'system',
  errno: 'ETIMEDOUT',
  code: 'ETIMEDOUT' }

Через несколько минут (5/6) без выполнения запросов приведенный выше код снова работает.

Я пытался с обоими node-fetch ( https://www.npmjs.com/package/node-fetch) и request ( https://www.npmjs.com/package/request). Те же результаты. Та же проблема возникает, если я не укажу agent и не связан с конечной точкой назначения, я пробовал с разными конечными точками (частными или общедоступными).

В соответствии с Microsoft Best Practices приложения node.js должны использовать поддержку активности agent со следующей конфигурацией:

var keepaliveAgent = new Agent({    
    maxSockets: 40,    
    maxFreeSockets: 10,    
    timeout: 60000,    
    keepAliveTimeout: 300000    
});

Фактически при создании агента с:

const agent = new https.Agent({ maxSockets: 100 });

все работает как положено.

Ожидается ли такое поведение? Какова лучшая практика для node.js? Хорошо всегда указывать agent с maxSockets также за пределами Лазурного?

ОБНОВИТЬ:

Другое странное поведение заключается в том, что если я запускаю приведенный выше код с помощью node index 3 или 4 раза я ожидаю, что соединения закрываются при выходе из процесса узла, но кажется, что соединения остаются открытыми в течение нескольких минут. Это может быть эффектом состояния TIME_WAIT?

0 ответов

Другие вопросы по тегам