#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. К вашему сведению, пул потоков вообще не влияет на сеть.