Как оптимизировать HTTP-опрос в NodeJS?

#node.js #http #axios #polling #keep-alive

#node.js #http #axios #опрос #keep-alive

Вопрос:

Я разрабатываю службу NodeJS, которая непрерывно опрашивает REST API для получения изменений состояния большого количества ресурсов практически в режиме реального времени. Другой протокол недоступен.

Интервал опроса составляет 5 секунд. Количество ресурсов обычно составляет от 100 до 500, поэтому давайте рассмотрим:

  • Обычно он выполняет 50 HTTP-запросов в секунду
  • Ответ часто занимает более 5 секунд, поэтому запросы на один и тот же запрос могут перекрываться

Часто средняя загрузка превышает 8,00 (на 8-ядерной виртуальной машине) и / или приложение выходит из строя.

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

Вот что я сделал:

  • Доступен HTTP2 (но не поддерживается axios?)
  • Установить process.env.UV_THREADPOOL_SIZE = 8
  • Используйте библиотеку axios для выполнения асинхронных запросов
  • Повторное использование одного и того же экземпляра axios для всех запросов
  • Используйте HTTPSAgent с keep-alive

Соответствующий код:

 'use strict'
process.env.UV_THREADPOOL_SIZE = 8

const axios = axios.create({
    baseURL: 'https://api.example.com',
    httpsAgent: new HTTPS.Agent({
        keepAlive: true,
        //maxSockets: 256,
        //maxFreeSockets: 128,
        scheduling: 'fifo',
        timeout: 1000 * 15
    }),
    timeout: 1000 * 15,
})

loadResource(id){
    return axios.request({
        method: 'GET',
        url: `/resource/${id}`
    })
    .catch((err) => {
        process.logger.error('Error with request (...)')
    })
    .then((res) => {
        handle(res)
    })
}

for(let id of [1,2,3,4,(...)]){
    setInterval(() => loadResource(id), 5000)
}

handle(res){...}
  

Что я рассматриваю:

  • Ожидание ответа перед отправкой нового запроса (и поиск наилучшего подхода для этого)

Что еще можно сделать для оптимальной обработки запросов?

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

1. Есть ли причина, по которой вы должны использовать опрос в первую очередь? Нет ли лучшего протокола, доступного для этого API? Вы также учитывали, что при использовании того же агента с keepalive ответы через HTTP / 1.1 будут блокировать другие ответы? HTTP / 2 был бы лучшим выбором, если он доступен. В противном случае вам все равно понадобится несколько подключений.

2. Используется HTTP2. Однако другого альтернативного транспорта нет. Спасибо.

3. Хорошо, итак, часть с перекрывающимися запросами … это требование? Со временем это приведет к увеличению нагрузки, которая в конечном итоге приведет к сбою. Есть ли какая-либо причина, по которой вы не стали бы ждать завершения запроса на ресурс, прежде чем пытаться извлечь его снова? (Другими словами, я бы не стал использовать setInterval() . Я бы использовал семафор или, по крайней мере, некоторую логику, которая обрабатывает ответ (или сбой) при загрузке ресурса, чтобы снова поставить в очередь загрузку этого ресурса.)

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

5. npmjs.com/package/await-semaphore