10

I have some timeout problems when calling multiple times an HTTP[S] endpoint from node.js inside an Azure App Service.

Here my code to demostrate the problem.

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);
});

When running this app 3 or 4 times inside a Standard Medium App Service (I'm running it using Kudu but I discover this error inside a standard web app) I get the following error for every requests:

{ 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' }

After some minutes (5/6) without performing requests the above code works again.

I have tried with both node-fetch (https://www.npmjs.com/package/node-fetch) and request (https://www.npmjs.com/package/request). Same results. The same problem occurs if I not specify an agent and is not related to the destination endpoint, I have tried with many different endpoints (private or public).

According to Microsoft Best Practices node.js applications should use a keep alive agent with the following configuration:

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

In fact when creating the agent with:

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

everything works as expected.

Is this behavior expected? What is the best practice for node.js? It is fine to always specify an agent with maxSockets also outside Azure?

UPDATE:

The other strange behavior is that if I run the above code using node index 3 or 4 times I expect that connections are closed when node process exit, but seems that the connections remain open for some minutes. This can be the effect of the TIME_WAIT state?

Davide Icardi
  • 11,919
  • 8
  • 56
  • 77

0 Answers0