Каков наилучший способ организации рабочих процессов в Rails? - PullRequest
15 голосов
/ 09 июля 2009

У меня часто есть какой-то код, который должен быть запущен либо по расписанию, либо как фоновый процесс с некоторыми параметрами. Общий элемент заключается в том, что они запускаются вне процесса диспетчеризации, но им необходим доступ к среде Rails (и, возможно, к передаваемым параметрам).

Какой хороший способ организовать это и почему? Если вам нравится использовать определенный плагин или гем, объясните, почему он вам удобен - не просто перечислите плагин, который вы используете.

Ответы [ 4 ]

8 голосов
/ 12 июля 2009

Мне действительно не нравятся такие гемы, как delayed_job и background_job, которые сохраняются в базе данных для выполнения асинхронных заданий. Это просто кажется мне грязным. Временный материал не принадлежит базе данных.

Я большой поклонник очередей сообщений для решения асинхронных задач, даже если вам не нужна огромная масштабируемость. На мой взгляд, очереди сообщений являются идеальным языком общения для сложных систем. С помощью очереди сообщений в большинстве случаев у вас нет ограничений на технологии или языки, которые задействованы во всем, что вы создаете. Преимущества использования очереди сообщений с низким уровнем параллелизма, вероятно, наиболее заметны в «корпоративной» среде, где интеграция всегда сопряжена с большими трудностями. Кроме того, очереди сообщений идеальны, когда ваш асинхронный рабочий процесс включает в себя несколько шагов. RabbitMQ - мой личный фаворит.

Например, рассмотрим сценарий, в котором вы создаете поисковую систему. Люди могут отправлять URI для индексации. Очевидно, что вы не хотите получать и индексировать страницу в запросе. Итак, вы строите вокруг очереди сообщений: цель отправки формы берет URI, выбрасывает его в очередь сообщений для индексации. Следующий доступный процесс-паук извлекает URI из очереди, извлекает страницу, находит все ссылки, помещает каждую из них обратно в очередь, если они неизвестны, и кэширует содержимое. Наконец, новое сообщение помещается во вторую очередь для процесса индексатора для обработки кэшированного содержимого. Процесс индексатора извлекает это сообщение из очереди и индексирует кэшированное содержимое. Конечно, слишком упрощенно - в поисковых системах много работы, но вы поняли.

Что касается настоящих демонов, то, очевидно, я неравнодушен к своей собственной библиотеке (ChainGang), но на самом деле это всего лишь обертка вокруг Kernel.fork (), которая дает вам удобное место для работы с кодом установки и демонтажа. Это также еще не совсем сделано. На самом деле часть демона гораздо менее важна, чем очередь сообщений.

Что касается среды Rails, то, пожалуй, лучше всего оставить это упражнение для читателя, поскольку использование памяти будет существенным фактором по сравнению с длительным процессом. Вы не хотите загружать то, что вам не нужно. Между прочим, это одна из областей, в которой DataMapper разумно пинает задницу ActiveRecord. Инициализация среды хорошо документирована, и в игру вступает гораздо меньше зависимостей, что делает весь набор и кабул значительно более реалистичным.

Единственное, что мне не нравится в cron + rake, это то, что rake практически гарантированно печатает на стандартный вывод, а cron имеет тенденцию быть слишком болтливым, если ваши задания cron выдают результат. Мне нравится помещать все мои задачи cron в каталог с соответствующим именем, а затем создавать rake-задачу, которая оборачивает их, так что запускать их вручную вручную тривиально. Обидно, что рейк делает это, потому что я действительно предпочел бы иметь возможность воспользоваться зависимостями. В любом случае, вы просто указываете cron непосредственно на сценарии, а не запускаете их через cron.

В настоящее время я занимаюсь созданием веб-приложения, которое в значительной степени опирается на асинхронные процессы, и я должен сказать, что я очень, очень рад, что решил не использовать Rails.

5 голосов
/ 09 июля 2009

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

В моем случае я использовал background_job и delayed_job . С background_job рабочий продолжал работать через cron, поэтому управление демоном отсутствовало. С delayed_job я использую Heroku и позволяю им беспокоиться об этом.

С помощью delayed_job вы можете передать столько аргументов, сколько необходимо вашему фоновому рабочему.

Delayed::Job.enqueue(MyJob.new(param[:one], param[:two], param[:three])

Я не нашел хорошего решения для запуска вещей по расписанию, кроме использования script/runner через cron (я предпочитаю использовать script/runner вместо задачи Rake, потому что мне проще тестировать код).

У меня никогда не было регулярного фонового процесса, для которого требовался доступ к определенному запросу Rails, чтобы это не было большой проблемой.

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

2 голосов
/ 09 июля 2009

У меня есть система, которая получает запросы, а затем должна вызвать несколько внешних систем, используя веб-сервисы. Некоторые из этих запросов занимают больше времени, чем пользователь может ожидать, и я использую корпоративную систему очередей (activemq) для обработки этих запросов.

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

Я видел Ryan Bates railscast на Старлинг и Уорлинг , и они выглядят многообещающе, но я не использовал их.

0 голосов
/ 09 июля 2009

Для задач с регулярным расписанием я просто использую грабли. Это просто, легко тестируется, легко понимается и хорошо интегрируется со средой Rails. Затем просто выполните эти грабли с помощью задания cron с любым интервалом, который вам требуется (я использую всякий раз, когда для управления этими заданиями, потому что я немного неграмотен).

...