Параллельные запросы Nodejs становятся медленнее

#node.js #performance #concurrency #parallel-processing #request

Вопрос:

У меня проблема с узлом, где для каждого сетевого запроса, который я добавляю в параллельную очередь, время, пока я не получу сетевой ответ, увеличивается на несколько миллисекунд, это нормально ? Если да, пожалуйста, скажите мне, почему они не должны тратить все время на ответ?

Настройка:
Локальный сервер ответов всегда обслуживает один и тот же ответ JSON объемом 300 КБ.
Способ запроса:

 const Q = require('q') let queue = [] for (var i = 100; i gt; 0; i--) {  queue.push(getDamageInfo()) }  Q.allSettled(queue) .then((result) =gt; {})  
 const Q = require('q') const request = require('request')  function getDamageInfo() {  id = '79d568d6-b820-40b4-845a-02228dcde338'  url = 'http://localhost:3001/damage/'  let deferred = Q.defer()  let start = new Date()  request.get(url   id , {  'auth': {  'bearer': token  }  }, (err, res, body) =gt; {  let end = new Date() - start  console.log('get-damage-info: '   id   ' %dms', end)  if(res.statusCode != 200) {  deferred.reject({statusCode: res.statusCode, error: err })  } else {  deferred.resolve(JSON.parse(body))  }  })   return deferred.promise }  

вывод на консоль:

 get-damage-info: 79d568d6-b820-40b4-845a-02228dcde338 43ms get-damage-info: 79d568d6-b820-40b4-845a-02228dcde338 44ms get-damage-info: 79d568d6-b820-40b4-845a-02228dcde338 46ms get-damage-info: 79d568d6-b820-40b4-845a-02228dcde338 48ms get-damage-info: 79d568d6-b820-40b4-845a-02228dcde338 51ms . . . get-damage-info: 79d568d6-b820-40b4-845a-02228dcde338 223ms get-damage-info: 79d568d6-b820-40b4-845a-02228dcde338 224ms get-damage-info: 79d568d6-b820-40b4-845a-02228dcde338 225ms  

Я не понимаю, почему время отклика уже увеличивается почти на 10 мс при 5 параллельных запросах с запроса 1 на запрос 5. Это происходит со всеми опробованными библиотеками (https, axios, запрос).

Заранее благодарю вас и хорошего дня

Ответ №1:

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

Ваш тестовый код отправляет 100 одновременных запросов.

Вам нужно понять, что Node.js также имеет ограниченное количество ресурсов и, в конце libuv концов, библиотека, реализующая асинхронность для Node.js использует пул потоков и что существует очередь заданий, которые он должен выполнить. Таким образом, чем больше работы в очереди, тем больше времени вам нужно подождать, прежде чем ваша работа будет выполнена. На самом деле существует несколько очередей, но это деталь реализации.

Кроме того, в конце концов, существуют некоторые аппаратные ограничения, например, у вас есть все 4 ядра в вашем процессоре, поэтому вся работа выполняется вашим процессором. Когда у вас больше работы на компьютере, это не увеличивает количество ядер, но уменьшает общее время отклика.

Комментарии:

1. Я понимаю, что чем больше запросов параллельно отправляется, тем больше времени может потребоваться серверу для их обработки. Но не должно ли это просто увеличить общее время, необходимое для завершения одного запроса? Например, при 5 параллельных запросах каждый запрос занимает 50 мс, в то время как при 10 параллельных запросах, возможно, каждый запрос занимает 70 мс. Tbh я не понимаю, почему они становятся последовательно медленнее, не должны ли они заканчиваться все одновременно, как после X мс каждый ?

2. Нет. Ваши действия добавляются в очередь в порядке FIFO, поэтому предположим, что ваша конечная точка выполняет какой-то вызов базы данных, для которого требуется какое-то сетевое задание, это происходит асинхронно, поэтому добавляется как задача где-то в очереди. Таким образом, задачи, которые добавляются в очередь в первую очередь, будут выполняться в первую очередь, сначала в первую очередь.