从 Azure 应用服务中的 node.js 多次调用 HTTP[S] 端点时,我遇到了一些超时问题。
这是我的代码来演示这个问题。
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 运行它,但我在标准 Web 应用程序中发现此错误)对于每个请求,我都会收到以下错误:
{ 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 最佳实践agent
,node.js 应用程序应使用具有以下配置的保持活动:
var keepaliveAgent = new Agent({
maxSockets: 40,
maxFreeSockets: 10,
timeout: 60000,
keepAliveTimeout: 300000
});
事实上,在创建代理时:
const agent = new https.Agent({ maxSockets: 100 });
一切都按预期工作。
这种行为是预期的吗?node.js 的最佳实践是什么?总是在 Azure 之外指定一个agent
with可以吗?maxSockets
更新:
另一个奇怪的行为是,如果我使用 3 或 4 次运行上述代码node index
,我希望在节点进程退出时连接会关闭,但似乎连接会保持打开几分钟。这可以是TIME_WAIT状态的影响吗?