繁体   English   中英

与https模块并发的API请求导致零星的ETIMEDOUT错误

[英]Concurrent API requests with https module results in sporadic ETIMEDOUT errors

我正在进行大量调用,由于重试的次数,我已经计算了16981次对我们的第三方API的调用。 总共不应有超过1000-1500个呼叫,因此其中绝大多数可能是重试。 我很早就收到409,所以我的请求代码重试,我认为这会导致级联问题。 调用次数过多后,我遇到了ETIMEDOUT错误,因此我再次尝试,这浪费了大量的执行时间。

我的ulimit是4864,所以我不知道它是否足够低而不能成为问题。

如何重构代码以更好地处理并发并避免这些不断重试? 我仍在学习,不确定如何解决此问题。

这是我的请求代码:

'use strict';

const https = require('https');
const Url = require('url');
const util = require('util');

function createRequest(requestUrl, body, requestHeaders, type = 'GET') {
    // Creates a post request at url with the given body

    return new Promise((resolve, reject) => {

        const retry = function() {
            // console.log('retrying...');
            createRequest(requestUrl, body, requestHeaders, type);
        }

        const parsedUrl = Url.parse(requestUrl, true, true);
        const options = {
            hostname: parsedUrl.hostname,
            path: parsedUrl.path,
            method: type,
            headers: requestHeaders
        };
        const req = https.request(options, (res) => {
            // console.log("Retry after: ", res.headers.date);
            let responseString = '';

            res.on('data', (dataChunk) => {
                responseString += dataChunk;
            });

            res.on('end', () => {
                if (res.statusCode === 200) {
                    resolve(responseString);
                } else if (res.statusCode === 409) {
                    setTimeout(function() {
                        return resolve(createRequest(requestUrl, body, requestHeaders, type));
                    }, res.headers['retry-after'] * 1000);
                }
            });
        });

        if (type === 'POST') {
            req.write(JSON.stringify(body));
        }

        req.on('error', (error) => {
            if (error.code === 'ETIMEDOUT') {
                //console.log('Encountered ETIMEDOUT. Retrying call...');
                console.log('MError: ', util.inspect(error, { showHidden: true, depth: 2 }));

                setTimeout(function() {
                    return resolve(createRequest(requestUrl, body, requestHeaders, type));
                }, 1000);
            }
            // reject(error);
        });

        req.end();
    });
}

module.exports = {
    createRequest
};

错误:

MError:  { Error: connect ETIMEDOUT 52.49.220.252:443
at Object.exports._errnoException (util.js:1018:11)
at exports._exceptionWithHostPort (util.js:1041:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1086:14)
  [message]: 'connect ETIMEDOUT 52.49.220.252:443',
  code: 'ETIMEDOUT',
  errno: 'ETIMEDOUT',
  syscall: 'connect',
  address: '52.49.220.252',
  port: 443 }

如果超时,则可以增加超时时间,但是https.request()不能提供相同的选项。 您可以使用相同的请求模块并设置超时的上限。 试试吧,让我知道。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM