Фоновые процессы в Node.js

99

Каков хороший подход для обработки фоновых процессов в приложении NodeJS?

Сценарий : после того, как пользователь отправит что-то в приложение, я хочу обработать данные, запросить дополнительные данные из внешних ресурсов и т. Д. Все это занимает довольно много времени, поэтому я хочу, чтобы это было вне цикла req / res. Идеально было бы просто иметь очередь заданий, в которой вы можете быстро сбросить задание, а демон или исполнитель задач всегда будет брать самое старое и обрабатывать его.

В RoR я бы сделал это с помощью чего-то вроде Delayed Job. Что представляет собой Node-эквивалент этого API?

Оле Спаарманн
источник
4
Вопрос - это рекомендация программного обеспечения, как она сформулирована сейчас, которая в конечном итоге будет закрыта. Если бы вы заменили последнее предложение на «Что такое NodeJS-эквивалент этого API?» он становится более актуальным. Я бы хотел, чтобы на этот вопрос ответили, а не закрыли, так как мне нужно сделать что-то подобное.
ssube
Спасибо, перефразировал.
Оле Спаарманн,
2
Хорошие предложения ниже. Также есть ChildProcessAPI, который может быть полезен. nodejs.org/api/child_process.html
lispHK01,
stackoverflow.com/users/69349/ole-spaarmann - Мне было бы интересно узнать, что вы в итоге выбрали, и не могли бы вы предоставить очень простой пример того, как вы интегрировали свое решение с NodeJS - спасибо!
MLissCetrus
@MLissCetrus Я решил изучить Elixir и больше не использовать NodeJS :)
Оле Спаарманн

Ответы:

114

Если вам нужно что-то легкое, работающее в том же процессе, что и сервер, я настоятельно рекомендую Bull . Он имеет простой API, который позволяет точно контролировать ваши очереди.

Если вы ищете что-то, что работает как отдельный рабочий процесс, возможно, посмотрите на Kue . Он может работать как сервер RESTful API и даже для него написано несколько интерфейсных приложений.

Если вы знакомы с Ruby Resque, существует реализация узла под названием Node-resque.

Bull, Kue и Node-resque поддерживаются Redis , который повсеместно встречается среди рабочих очередей Node.js. Все трое смогут делать то, что делает DelayedJob RoR, это зависит от конкретных функций, которые вы хотите, и ваших предпочтений API.

Юрий Зарубин
источник
3
Это очень хороший ответ, но упоминание о модуле ChildProcess API и webworker-thread может сделать его отличным. ;)
ssube
@ssube Я с тобой не согласен. Если вы не имеете в виду создание форка, который смотрит на очередь для выполнения какой-либо команды, вы правы. +1 от меня. Я использую Child_process, и моя проблема в том, что я могу открыть огромный набор процессов, но если бы у меня был способ управлять задачами, которые должны запускаться в очереди, я был бы счастлив, что CP - хорошее решение. Это можно сделать, но суть в том, чтобы не выполнять всю работу самостоятельно, а повторно использовать проверенный в бою код (в данном случае что-то вроде Kue, который выполняет всю необходимую вам магию и допускает интеграцию API).
dewwwald
Работает ли Bull с кластеризацией PM2? Или вам нужно создавать собственные кластеры вручную, как показано в их документации?
Шаян Нахрвар
33

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

Одним из хороших вариантов обмена сообщениями между двумя процессами будет redis , если время от времени отбрасывать сообщение - это нормально. Если вы не хотите, чтобы сообщения оставались позади, вам понадобится более крупный брокер, такой как Rabbit . Процесс веб-службы может публиковать, а процесс фоновой работы может подписываться.

Необязательно, чтобы два процесса размещались совместно, они могут находиться на разных виртуальных машинах, контейнерах Docker, что бы вы ни использовали. Это позволяет масштабировать без особых проблем.

черника
источник
4
Неужели единственный ответ, в котором упоминался Кролик? Это корпоративный ответ. +1
Оги Гарднер
@wberry Изменится ли ваш ответ с учетом рабочих потоков Nodejs?
Брендан,
Я не работал с Node уже несколько лет. Но эта новая многопоточная система кажется противоречащей первоначальному замыслу языка. Мой инстинкт состоит в том, чтобы избегать использования этого модуля, за исключением тех узких случаев, для которых он предназначен - вычисления с интенсивным использованием ЦП, которые неудобно реализовать с помощью setImmediateвызовов.
wberry
Основные проблемы при объединении служебного и транзакционного кода в одном процессе - это память и ввод-вывод. Если служебный код превращается в боров, это может повлиять на трафик. Использование пакета Worker устранит необходимость в брокере, но подвергнет вас этим рискам.
wberry
11

Если вы используете MongoDB, я рекомендую Agenda . Таким образом, отдельные экземпляры Redis не работают и присутствуют такие функции, как планирование, организация очередей и веб-интерфейс. Пользовательский интерфейс повестки дня является необязательным и, конечно же, может запускаться отдельно.

Также рекомендовал бы настроить слабосвязанную абстракцию между логикой вашего приложения и системой очередей / планирования, чтобы при необходимости можно было заменить всю систему фоновой обработки. Другими словами, держите как можно больше логики приложений / обработки в определениях заданий в повестке дня, чтобы они были легкими.

sean2078
источник
3

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

Вы упомянули RoR и DJ, поэтому я предполагаю, что вы знакомы с sidekiq. Вы можете использовать node-sidekiq для планирования заданий, если хотите, но это неоптимально imo, поскольку его основной целью является интеграция nodejs с RoR.

Для демонизации рабочих я бы рекомендовал использовать PM2 . Он широко используется и активно поддерживается. Он решает множество проблем (например, развертывание, мониторинг, кластеризацию), поэтому убедитесь, что это не станет для вас излишним.

Стефкин
источник
1

Я попробовал bee-queue & bull и в итоге выбрал быка. Сначала я выбрал bee-queue b / c, это довольно просто, их примеры легко понять, а примеры быков немного сложны. Bee 's wiki Происхождение Bee Queue's Origin также находит отклик у меня. Но проблема с пчелами в том, что <1> время их решения довольно медленное, последнее обновление было 10 месяцев назад. <2> Я не могу найти простой способ приостановить / отменить задание.

Bull, с другой стороны, часто обновляет свои коды, отвечая на проблемы. Оценка очереди заданий Node.js показала, что слабость быка - "медленное время решения проблем", но мой опыт противоположен!

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

Qiulang
источник
-7

Я предлагаю использовать подходящую структуру Node.js для создания приложения.

Я думаю, что самый мощный и простой в использовании - это Sails.js .

Это фреймворк MVC, поэтому, если вы привыкли разрабатывать в ROR, вам будет очень просто!

Если вы его используете, он уже представляет собой мощный (в терминах javascript) менеджер заданий.

new sails.cronJobs('0 01 01 * * 0', function () {
   sails.log.warn("START ListJob");
}, null, true, "Europe/Dublin");

Если вам нужна дополнительная информация, не стесняйтесь обращаться ко мне!

Зио Мак Со
источник
6
Я ищу диспетчер фоновых процессов для Node. По определению это должно быть отделено от вашего веб-приложения. И неважно, используете ли вы Sails, Express, Hapi или что-то еще.
Оле Спаарманн
Хорошо, вы можете попробовать Bull или Webworker-Threads ... удачи с Node.js :)
Zio Mak Sò
Похоже, что sails.js довольно большой и делает гораздо больше, чем cronJobs. Я нашел node-cron ( github.com/kelektiv/node-cron ), который, держу пари, использует sails.js.
pbatey