У меня был похожий вопрос о длинных запросах, которые блокируют работников принимать другие запросы.Это проблема со всеми веб-приложениями.Даже Node.js может быть не в состоянии решить проблему, отнимающую слишком много времени у рабочего, или может просто не хватить памяти.
Веб-приложение, над которым я работал, имеет веб-интерфейс, который отправляет запрос в RailsREST API, затем контроллер Rails должен запросить Node REST API, который выполняет трудоемкую задачу, чтобы вернуть некоторые данные.Запрос от Rails к Node.js может занять 2-3 минуты.
Мы все еще пытаемся найти разные подходы, но, возможно, следующее может работать для вас, или вы можете адаптировать некоторые идеи, я бы хотелчтобы получить также отзывы:
- Frontend делает запрос к Rails API с сгенерированным идентификатором [A] в том же сеансе.(этот идентификатор помогает идентифицировать предыдущий запрос из того же сеанса пользователя).
- Rails API передает запрос внешнего интерфейса и идентификатор [A] в службу Node.js
Node.Служба js добавляет это задание в систему очередей (например, RabbitMQ или Redis), сообщение содержит идентификатор [A].(Здесь вы должны подумать, основываясь на своем собственном сценарии, также предполагая, что система будет использовать задание очереди и сохранит результаты)
Если тот же запрос будет отправлен снова, в зависимости от требования,вы можете либо убить текущее задание с тем же идентификатором [A] и запланировать / поставить в очередь последний запрос, либо проигнорировать последний запрос, ожидающий завершения первого, либо другое решение соответствует вашим бизнес-требованиям.
Интерфейс может отправлять интервальный запрос REST, чтобы проверить, завершена ли обработка данных с идентификатором [A] или нет, тогда эти запросы являются легкими и быстрыми.
Как только Node.js завершит работу, вы можете либо воспользоваться системой подписки на сообщения, либо дождаться следующего запроса проверки статуса и вернуть результат во внешний интерфейс.
Вы также можете использоватьбалансировщик нагрузки, например Amazon балансировщик нагрузки, Haproxy .В 37signals есть пост в блоге и видео об использовании Haproxy для выгрузки некоторых долгосрочных запросов, которые не блокируют более короткие.
Github использует аналогичную стратегию для обработки длинных запросов для генерации коммитов / визуализации вклада,Они также устанавливают предел времени вытягивания.Если время слишком велико, Github отображает сообщение о том, что оно слишком длинное и оно было отменено.
У YouTube есть приятное сообщение для задач с более длинными очередями: «Это занимает больше времени, чем ожидалось. Ваше видео было поставлено в очередь и будет обработано как можно скорее».
Я думаю, что это простоодно решениеВы также можете взглянуть на EventMachine gem, который помогает повысить производительность, обрабатывать параллельные или асинхронные запросы.
Поскольку проблема такого рода может включать одну или несколько служб.Подумайте о возможности улучшения производительности между этими службами (например, база данных, сеть, протокол сообщений и т. Д.), Если кэширование может помочь, попробуйте кешировать частые запросы или предварительно рассчитать результаты.