Не удается достичь параллелизма http-запросов

#javascript #node.js #axios #dom-events #node-modules

#javascript #node.js #axios #dom-события #узлы-модули

Вопрос:

У меня есть приложение, написанное на Node, которое отправляет Http-запросы в цикле на один веб-сервер и регистрирует, сколько запросов он получает каждые 1 секунду. Моя проблема в том, что я получаю максимум 10 запросов в секунду, что абсолютно мало, учитывая тот факт, что у меня доступно 2 16 портов и большая скорость загрузки / выгрузки. Когда я использую некоторые другие языки низкого уровня, которые поддерживают многопоточность, такие как Java, мне удается получать около 600-700 запросов в секунду, что намного больше, чем это число. Мой код очень тривиален, и единственное, что я делаю, это выполняю бесконечный цикл и отправляю запросы на веб-сервер, а в ответ увеличиваю глобальную переменную, которую я печатаю каждые 1 секунду, чтобы понять, сколько запросов вернулось.

 async function sendTestRequest() {
    var uUrl = 'https://sometestwebserver.io/';

    axios.get(uUrl, {
        jar: cookieJar, // tough.CookieJar or boolean
        headers: {
            'Accept': 'text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
            'Connection': 'keep-alive',
            'Sec-Fetch-Dest': 'document',
            'Sec-Fetch-Mode': 'navigate',
            'Sec-Fetch-Site': 'none',
            'Sec-Fetch-User': '?1',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36'
        },
        withCredentials: true
    }).then(response => {
        bmak.globalCnt  ;
    }).catch(error => {
        console.log(error);
    })
};

async function main() {
    bmak.globalCnt = 0;
    var currDate = Date.now();
    for (let w = 0; 1 == 1; w  ) {
            sendTestRequest()
            if (Date.now() - currDate >= 1000) {
                console.log("Received requests: "   bmak.globalCnt);
                currDate = Date.now();
            }
            continue;
}}
  

Ответ №1:

Держу пари, это потому, что ваш main() цикл событий голодает. Он синхронно вызывает sendTestRequest бесконечно, никогда не передавая управление потоком JavaScript для обработки ввода-вывода.

Я бы переработал это, чтобы обеспечить максимальный параллелизм. main() следует вызывать sendTestRequest() это количество раз, а затем, когда ваш HTTP-запрос завершается (т. Е. В then / catch callbacks ), вызовите sendTestRequest снова.

Затем вы можете немного поэкспериментировать, чтобы найти число параллелизма, которое обеспечит вам наилучшую производительность.

PS: async s, используемые в этом примере, совершенно не нужны, поскольку вы на самом деле не await даете никаких обещаний. Вы не должны использовать async , если вам это действительно не нужно, поскольку это увеличивает нагрузку на время выполнения.