Задание cron для rails: лучшие практики?

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

20 ответов


Я использую подход рейка (как поддерживается здесь)

с файлом под названием lib/tasks / cron.выгребать..

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

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

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

  • команду Heroku службы cron я ссылки заменил by В Heroku Планировщик
  • для частых задач (esp. где вы хотите избежать стоимости запуска среды Rails) мой предпочтительный подход-использовать системный cron для вызова скрипта, который будет либо (a) тыкать безопасный/частный API webhook для вызова требуемой задачи в фоновом режиме, либо (b) напрямую запрашивать задачу в вашей системе очереди выбора

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

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

пример из 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

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

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

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

затем мы перешли к РУФУС ПЛАНИРОВЩИК 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


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

планировщик Rufus делает это за меня (https://github.com/jmettraux/rufus-scheduler)

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

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


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


задачи script / runner и rake отлично подходят для запуска в качестве заданий cron.

здесь одна очень важная вещь, которую вы должны помнить при выполнении задания. Вероятно, они не будут вызываться из корневого каталога Вашего приложения. Это означает, что все ваши требования к файлам (в отличие от библиотек) должны выполняться с явным путем: например, файл.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; -)


оба будут работать нормально. Обычно я использую script / runner.

вот пример:

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

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

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


использовать Craken (грабли центральные cron задания)


что интересно, никто не упомянул о 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

Я использую backgroundrb.

http://backgroundrb.rubyforge.org/

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


вот как я настроил свои задачи cron. У меня есть один, чтобы сделать ежедневные резервные копии базы данных SQL (с помощью rake), а другой, чтобы истекать кэш один раз в месяц. Любой вывод регистрируется в файле log / cron_log. Мой crontab выглядит так:

crontab -l # command to print all cron tasks
crontab -e # command to edit/add cron tasks

# Contents of crontab
0 1 * * * cd /home/lenart/izziv. whiskas.si/current; /bin/sh cron_tasks >> log/cron_log 2>&1
0 0 1 * * cd /home/lenart/izziv.whiskas.si/current; /usr/bin/env /usr/local/bin/ruby script/runner -e production lib/monthly_cron.rb >> log/cron_log 2>&1

первая задача cron создает ежедневные резервные копии БД. Содержимое cron_tasks выглядит следующим образом:

/usr/local/bin/rake db:backup RAILS_ENV=production; date; echo "END OF OUTPUT ----";

вторая задача была настроена позже и использует скрипт / runner для истечения срока действия кэша один раз в месяц (lib / monthly_cron.rb):

#!/usr/local/bin/ruby
# Expire challenge cache
Challenge.force_expire_cache
puts "Expired cache for Challenges (Challenge.force_expire_cache) #{Time.now}"

думаю, я мог бы создать резервную копию базы данных каким-то другим способом, но пока это работает для меня :)

на пути грабли и Рубин могут отличаться на разных серверах. Вы можете увидеть, где они находятся, используя:

whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake

использование чего-то Sidekiq или Resque-гораздо более надежное решение. Они оба поддерживают повторные задания, эксклюзивность с блокировкой REDIS, мониторинг и планирование.

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


недавно я создал несколько заданий cron для проектов, над которыми я работал.

Я нашел, что камень часам очень полезно.

require 'clockwork'

module Clockwork
  every(10.seconds, 'frequent.job')
end

вы даже можете запланировать фоновую работу с помощью этого драгоценного камня. Для документации и дальнейшей помощи обратитесь https://github.com/Rykian/clockwork


однажды мне пришлось принять такое же решение и я очень доволен, что сегодня решение. Использовать resque планировщик потому что не только отдельный redis снимет нагрузку с вашей БД, у вас также будет доступ ко многим плагинам, таким как resque-web, который обеспечивает отличный пользовательский интерфейс. По мере развития вашей системы у вас будет все больше и больше задач для планирования, чтобы вы могли контролировать их из одного места.


вы можете использовать resque и resque - shheduler gem для создания крон, это очень легко сделать.

https://github.com/resque/resque

https://github.com/resque/resque-scheduler


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

вы можете увидеть очень полезно видео на railscasts

также взгляните на эти другие ресурсы:


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


Я не совсем уверен, я думаю, это зависит от задачи: как часто запускать, насколько сложно и сколько требуется прямая связь с проектом rails и т. д. Я думаю, если бы было просто "Один Лучший Путь" чтобы что-то сделать, не было бы так много разных способов сделать это.

на моей последней работе в проекте Rails нам нужно было сделать пакетную рассылку приглашений (приглашения на опрос, а не спам), которая должна отправлять запланированные письма всякий раз, когда у сервера было время. Я думаю, мы собирались использовать daemon tools для запуска задач rake, которые я создал.

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


Я использую скрипт для запуска cron, это лучший способ запустить cron. Вот пример для cron,

открыть CronTab - > sudo crontab-e

и вставить строки ниже:

00 00 * * * wget https://your_host/some_API_end_point

вот некоторые cron формат, поможет вам

::CRON FORMAT::

cron format table

Examples Of crontab Entries
15 6 2 1 * /home/melissa/backup.sh
Run the shell script /home/melissa/backup.sh on January 2 at 6:15 A.M.

15 06 02 Jan * /home/melissa/backup.sh
Same as the above entry. Zeroes can be added at the beginning of a number for legibility, without changing their value.

0 9-18 * * * /home/carl/hourly-archive.sh
Run /home/carl/hourly-archive.sh every hour, on the hour, from 9 A.M. through 6 P.M., every day.

0 9,18 * * Mon /home/wendy/script.sh
Run /home/wendy/script.sh every Monday, at 9 A.M. and 6 P.M.

30 22 * * Mon,Tue,Wed,Thu,Fri /usr/local/bin/backup
Run /usr/local/bin/backup at 10:30 P.M., every weekday. 

надеюсь, это поможет вам:)