Подключайте 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?