Статьи

Сравнение библиотек фоновой обработки: Resque

Люди и дверь синие

Это вторая часть серии, посвященной сравнению сред фоновой обработки Ruby. Вы можете проверить предыдущий пост, связанный выше. Подводя итоги первого поста, он охватывает принципы фоновой обработки (очереди, процессы и т. Д.). Кроме того, в статье рассматривается задержка_job (а также способы ее использования для создания фоновой работы и ее обработки), которая отлично подходит для быстрой фоновой обработки в вашем приложении. Тем не менее, он использует ActiveRecord, поэтому он довольно медленный, и вы в конечном итоге смешиваете фоновый и основной код во всем приложении.

Resque надеется решить обе эти проблемы, так что давайте окунемся!

Resque

Чтобы использовать Resque, вам нужно установить Redis. К счастью, у них есть отличная документация по установке . Если вы работаете в Mac OS X (как и многие из нас), все, что вам нужно сделать:

brew install redis 

В Linux возможно установить Redis через менеджер пакетов. Например, в Debian / Ubuntu:

 sudo apt-get install redis-server 

Redis, к сожалению, не поддерживает Windows. Был представлен порт, но он не был объединен.

Установив Redis и запустив сервер Redis, вы можете добавить Resque в свой Gemfile:

 gem 'resque' 

А затем установите пакет:

 bundle install 

Вам нужно настроить грабли, которые позволят вам запустить рабочих с вашим Rails-приложением. Для этого добавьте файл в каталог «lib / tasks» с именем «resque.rake» (это определит задачи rake, связанные с Resque):

 require 'resque/tasks' 

Если вашим работникам нужен доступ к моделям (т. Е. Для фоновой обработки, которую вы будете выполнять, потребуется доступ к ActiveRecord и т. Д.), Вам необходимо добавить в этот файл следующее (lib / tasks / resque.rake):

 task "resque:setup" => :environment 

Наконец, вы должны создать отдельный каталог для ваших работников, так как они будут работать независимо от других аспектов вашего Rails-приложения. Я использую «приложение / работники» для этого.

Теперь, когда у нас есть начальная настройка, давайте напишем нашу первую работу с Resque. Сохраните следующее в app/workers/print_worker.rb

 class PrintWorker @queue = :print def self.perform(str) puts "From print worker: " + str end end 

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

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

В частности, PrintWorker выполняет очень простую задачу; он берет строку, а затем печатает ее со специальной запиской «От печатника» перед ней.

Однако сейчас это не делает никакой работы; класс просто определен (т. е. в очереди нет заданий). Давайте это исправим.

Вот простой контроллер индекса (очевидно, вы можете взять материал внутри действия и поместить его в любой контроллер вашего приложения):

 class IndexController < ApplicationController def index Resque.enqueue(PrintWorker, params[:to_print]) end end 

Еще один очень простой фрагмент кода. Все, что он делает — это получает запрос пользователя на «index # index», а затем добавляет задание для работника печати. Но важный бит — это params[:to_print] , который фактически указывает, что строка, которую PrintWorker напечатает, определяется параметром GET переданным действию index .

Если мы перейдем к «/ index / index? To_print = somestring», PrintWorker должен распечатать «somestring».

Однако где же это будет напечатано? Нам нужно настроить рабочий процесс! В отличие от delayed_job, Resque требует, чтобы вы настроили рабочий процесс, который «потребляет» очередь заданий. Давайте сделаем это прямо сейчас, набрав в терминале следующее:

 rake resque:work QUEUE=print 

Мы просто использовали одну из задач rake, предоставляемых resque, чтобы запустить рабочий процесс в очереди с именем print. Теперь это должно дать вам процесс, который, похоже, ничего не делает.

Укажите в вашем браузере «/ index / index? To_print = lol» (с правильным именем хоста, конечно) и проверьте вывод процесса, и вы должны увидеть, что печатник напечатал: «С печатника: lol».

Очевидно, это кажется очень простым примером, и это так. Но это действительно охватывает центральную идею resque; Работники определяются как классы с методом execute, очереди именуются, и вы можете передавать переменные работникам.

Хорошо, теперь, когда мы это знаем, давайте посмотрим на Resque по сравнению с delayed_job. Очевидно, с задержкой гораздо легче начать работу. Но, по моему мнению, код delayed_job имеет тенденцию извиваться довольно быстро, если вы не будете осторожны, потому что вы можете смешивать асинхронные вызовы с синхронными вызовами для одного и того же метода. Delayed_job также, вероятно, будет медленнее, так как он не использует хранилище в памяти по умолчанию.

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

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

Пример приложения

Чтобы продемонстрировать базовое использование Resque (а также быстро протестировать ваш экземпляр Redis), я создал небольшой пример приложения, которое позволяет вам запускать несколько простых рабочих на вашем компьютере. Он выполняет ту же функцию, что и пример приложения для delayed_job: асинхронно и синхронно выполняет подсчет страниц в файле. Это очень простое приложение, но оно служит рабочим примером для дальнейшего развития.

Проверьте это здесь

Будьте на связи!

В третьей части этой статьи будет рассказано о Sidekiq, а также общее сравнение трех фреймворков, которые обсуждались до сих пор (DelayedJob, Resque, Sidekiq).