Стратегия разгрузки для более длительных задач в Express Routes

У меня есть приложение, которое использует Express в качестве пользовательской среды для моего REST API вместе с RabbitMQ для вызовов функций, подобных RPC, для кластерного бэкэнда. Кроме того, я использую Q, чтобы обещать всю свою нагрузку в Routes.

В одном из маршрутов, которые я использую, я запускаю некоторые функции, которые сканируют URL-адрес, указанный в параметрах маршрута, выполняют поиск GeoIP, нормализуют форматы результатов и т. д. Это может занять несколько секунд, в зависимости от времени отклика серверов просканированного URL-адреса.

Чего я хотел бы добиться, так это того, что пользователь, который отправляет новый URL-адрес для сканирования, получает немедленную обратную связь на свой запрос (статус 200 = «Запрос на сканирование подтвержден») и не ожидает запроса, ожидающего завершения сканирования.

Мои идеи либо

  • Отправка URL-адреса в определенную очередь в RabbitMQ и наличие другого процесса для прослушивания заданий очереди
  • Использование чего-то вроде дочерних процессов внутри Express Routes

Что было бы лучшим решением для решения этой проблемы? Спасибо за ваш ценный вклад.


person Tobi    schedule 19.02.2015    source источник


Ответы (1)


Очень загруженный вопрос имеет множество вариантов, каждый из которых по-своему влияет на систему в целом. Не уверен, что есть правильный ответ. Это действительно вопрос предпочтений и того, что вам удобно. ИМО, я бы постарался все упростить. Добавление другого процесса (RabbitMQ) означает другой программный пакет (или даже целый сервер) для управления, настройки, разрешения и защиты.

Несколько вещей, чтобы рассмотреть. Привязана ли основная часть ваших операций ввода-вывода или ЦП? Если вы используете удаленную службу для поиска GeoIP, это может быть больше связано с вводом-выводом, что идеально подходит для node. Почему бы не сделать так, чтобы node просто обрабатывал все через:

process.nextTick(function() {
  // Do your lookup here
}

res.status(201).end();

Затем используйте что-то вроде socket.io для асинхронной отправки результатов клиенту?

В любом случае, я бы рекомендовал возвращать 202 - Accepted, а не 200.

person barefootsanders    schedule 19.02.2015
comment
Большое спасибо за ответ. Я уже использую RabbitMQ в основном для вызовов функций RPC к серверному кластеру, поэтому добавление еще одной службы/сервера не является проблемой. Дело в том, что использование другой очереди с RabbitMQ заключается в том, что мне нужно будет запустить другой процесс для прослушивания соответствующей очереди. В настоящее время сканирование реализовано в функции RPC, которая затем возвращает результаты сканирования. Это оказалось нежизнеспособным из-за времени отклика. Мне на самом деле нравится идея process.nextTick(function() {});, и я проверю это... - person Tobi; 19.02.2015
comment
Кстати, это 202 Accepted :-) Спасибо и за эту подсказку. - person Tobi; 19.02.2015
comment
Вау, не могу поверить, что я толстые пальцы, что один. Оригинал обновлен. - person barefootsanders; 19.02.2015
comment
Мир как очарование. Большое спасибо! - person Tobi; 20.02.2015
comment
Нет проблем - рад это слышать! - person barefootsanders; 20.02.2015