Работа cron для рельсов: лучшие практики? - PullRequest
294 голосов
/ 13 ноября 2008

Каков наилучший способ запуска запланированных задач в среде Rails? Сценарий / бегун? Рейк

Ответы [ 20 ]

252 голосов
/ 17 июня 2011

Я использовал чрезвычайно популярный Всякий раз, когда в проектах, которые сильно зависят от запланированных задач, и это здорово. Это дает вам хороший DSL для определения ваших запланированных задач вместо того, чтобы иметь дело с форматом crontab. ОТ README:

Всякий раз, когда рубиновый камень, который обеспечивает четкий синтаксис для написания и развертывания Cron Job.

Пример из README:

every 3.hours do
  runner "MyModel.some_process"       
  rake "my:rake:task"                 
  command "/usr/bin/my_great_command"
end

every 1.day, :at => '4:30 am' do 
  runner "MyModel.task_to_run_at_four_thirty_in_the_morning"
end
110 голосов
/ 15 июня 2009

Я использую рейк-подход (поддерживаемый heroku )

С файлом с именем lib / tasks / cron.rake ..

task :cron => :environment do
  puts "Pulling new requests..."
  EdiListener.process_new_messages
  puts "done."
end

Чтобы выполнить из командной строки, это просто "rake cron". Затем эту команду можно при желании поместить в cron / планировщик задач операционной системы.

Обновление это довольно старый вопрос и ответ! Некоторая новая информация:

  • Служба HeroKron, на которую я ссылался, была заменена Heroku Scheduler
  • для частых задач (особенно там, где вы хотите избежать затрат на запуск среды Rails), я предпочитаю использовать системный cron для вызова скрипта, который будет либо (a) использовать безопасный / приватный API webhook для вызова необходимой задачи в фоновом режиме или (b) поставьте задачу в очередь в выбранной вами системе очередей
17 голосов
/ 10 августа 2013

В нашем проекте мы впервые использовали gem, но столкнулись с некоторыми проблемами.

Затем мы переключились на RUFUS SCHEDULER gem, который оказался очень простым и надежным для планирования задач в Rails.

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

Код, используемый в этом, похож на:

    require 'rufus-scheduler'

    scheduler = Rufus::Scheduler.new

    scheduler.in '10d' do
      # do something in 10 days
    end

    scheduler.at '2030/12/12 23:30:00' do
      # do something at a given point in time
    end

    scheduler.every '3h' do
      # do something every 3 hours
    end

    scheduler.cron '5 0 * * *' do
      # do something every day, five minutes after midnight
      # (see "man 5 crontab" in your terminal)
    end

Чтобы узнать больше: https://github.com/jmettraux/rufus-scheduler

16 голосов
/ 13 ноября 2008

Если ваши задачи не займут много времени, просто создайте новый контроллер с действием для каждой задачи. Реализуйте логику задачи в виде кода контроллера. Затем установите cronjob на уровне ОС, который использует wget для вызова URL-адреса этого контроллера и действия в соответствующие промежутки времени. Преимущества этого метода:

  1. Полный доступ ко всем вашим объектам Rails, как и в обычном контроллере.
  2. Может разрабатывать и тестировать так же, как вы делаете обычные действия.
  3. Может также вызывать ваши задачи adhoc с простой веб-страницы.
  4. Не потребляйте больше памяти, запуская дополнительные процессы ruby ​​/ rails.
10 голосов
/ 22 февраля 2013

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

Планировщик Руфуса делает это для меня (https://github.com/jmettraux/rufus-scheduler)

Когда мне нужно выполнить длинные задания, я использую его с delayed_job (https://github.com/collectiveidea/delayed_job)

Надеюсь, это поможет!

10 голосов
/ 11 июня 2013

Я большой поклонник resque / resque scheduler . Вы можете запускать повторяющиеся задачи, похожие на cron, но и задачи в определенное время. Недостатком является то, что для этого требуется сервер Redis.

9 голосов
/ 13 октября 2015

Что интересно, никто не упомянул Sidetiq . Это хорошее дополнение, если вы уже используете Sidekiq.

Sidetiq предоставляет простой API для определения повторяющихся работников для Sidekiq.

Работа будет выглядеть так:

class MyWorker
  include Sidekiq::Worker
  include Sidetiq::Schedulable

  recurrence { hourly.minute_of_hour(15, 45) }

  def perform
    # do stuff ...
  end
end
9 голосов
/ 13 ноября 2008

Сценарии / runner и rake-задачи прекрасно подходят для выполнения заданий cron.

Вот одна очень важная вещь, которую вы должны помнить при запуске заданий cron. Они, вероятно, не будут вызываться из корневого каталога вашего приложения. Это означает, что все ваши требования к файлам (в отличие от библиотек) должны выполняться с явным путем: например, File.dirname (__ FILE__) + "/ other_file". Это также означает, что вы должны знать, как явно вызывать их из другого каталога: -)

Проверьте, поддерживает ли ваш код запуск из другого каталога с

# from ~
/path/to/ruby /path/to/app/script/runner -e development "MyClass.class_method"
/path/to/ruby /path/to/rake -f /path/to/app/Rakefile rake:task RAILS_ENV=development

Кроме того, задания cron, вероятно, не выполняются как вы, поэтому не зависите от ярлыков, которые вы вставляете в .bashrc. Но это просто стандартный совет cron; -)

8 голосов
/ 14 ноября 2008

Оба будут работать нормально. Я обычно использую скрипт / бегун.

Вот пример:

0 6 * * * cd /var/www/apps/your_app/current; ./script/runner --environment production 'EmailSubscription.send_email_subscriptions' >> /var/www/apps/your_app/shared/log/send_email_subscriptions.log 2>&1

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

Следует помнить одну вещь, если память драгоценна, это то, что скрипт / бегун (или задача Rake, зависящая от «среды») загрузит всю среду Rails. Если вам нужно только вставить некоторые записи в базу данных, это будет использовать память, которая вам на самом деле не нужна. Если вы пишете свой собственный сценарий, вы можете избежать этого. На самом деле мне еще не нужно было это делать, но я обдумываю это.

8 голосов
/ 29 декабря 2008

Использование Craken (рейк-ориентированные задания cron)

...