Каков наилучший способ запуска запланированных задач в среде Rails? Сценарий / бегун? Грабли? Я хотел бы запускать задачу каждые несколько минут.
Каков наилучший способ запуска запланированных задач в среде Rails? Сценарий / бегун? Грабли? Я хотел бы запускать задачу каждые несколько минут.
Ответы:
Я использую рейк-подход (как поддерживает heroku )
С файлом с именем lib / tasks / cron.rake ..
task :cron => :environment do
puts "Pulling new requests..."
EdiListener.process_new_messages
puts "done."
end
Чтобы выполнить из командной строки, это просто "rake cron". Эта команда затем может быть помещена в cron / планировщик задач операционной системы по желанию.
Обновите это довольно старый вопрос и ответ! Некоторая новая информация:
load "#{Rails.root}/lib/tasks/cron.rake"
и rake cron
, но получил NameError: неопределенная локальная переменная или метод `cron 'для main: Object
:environment
зависимости. У нас очень тяжелое Rails-приложение, которое требует много времени для запуска, наш Rake вызывается каждую минуту и потребляет больше ресурсов для запуска среды Rails, которая выполняет задачу . Я хотел бы, чтобы уже запущенная среда Rails вызывалась через cron, должна быть что-то среднее между подходом контроллера и средой rake .
Я использовал чрезвычайно популярный проект всякий раз, когда он сильно зависит от запланированных задач, и это здорово. Это дает вам хороший DSL для определения ваших запланированных задач вместо того, чтобы иметь дело с форматом crontab. Из README:
Всякий раз, когда это Ruby-гем, который предоставляет четкий синтаксис для написания и развертывания заданий cron.
Пример из 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
В нашем проекте мы впервые использовали gem, но столкнулись с некоторыми проблемами.
Затем мы переключились на гем RUFUS SCHEDULER , который оказался очень простым и надежным для планирования задач в 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
Предполагая, что выполнение ваших задач не занимает много времени, просто создайте новый контроллер с действием для каждой задачи. Реализуйте логику задачи в виде кода контроллера, затем настройте cronjob на уровне ОС, который использует wget для вызова URL-адреса этого контроллера и действия в соответствующие промежутки времени. Преимуществами этого метода являются вы:
Задачи script / 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 ;-)
Проблема с всякий раз, когда (и cron) перезагружается среда rails каждый раз, когда она выполняется, что является реальной проблемой, когда ваши задачи выполняются часто или у вас много работы по инициализации. У меня были проблемы с производством из-за этого, и я должен предупредить вас.
Планировщик Rufus делает это для меня ( https://github.com/jmettraux/rufus-scheduler )
Когда у меня есть длинные задания для выполнения, я использую его с delayed_job ( https://github.com/collectiveidea/delayed_job )
Надеюсь, это поможет!
Я большой поклонник Resque / Resque Scheduler . Вы можете запускать повторяющиеся задачи, похожие на cron, но и задачи в определенное время. Недостатком является то, что для этого требуется сервер Redis.
Это интересно, никто не упомянул 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
Оба будут работать нормально. Я обычно использую скрипт / бегун.
Вот пример:
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. Если вам нужно только вставить некоторые записи в базу данных, это будет использовать память, которая вам на самом деле не нужна. Если вы пишете свой собственный сценарий, вы можете избежать этого. На самом деле мне еще не нужно было это делать, но я обдумываю это.
Используйте Craken (рейк-ориентированные задания cron)
Я использую 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 / month_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 запускает каждого рабочего в отдельном процессе.
Недавно я создал несколько рабочих мест для проектов, над которыми я работал.
Я обнаружил, что драгоценный камень Заводной очень полезен.
require 'clockwork'
module Clockwork
every(10.seconds, 'frequent.job')
end
Вы можете даже запланировать свою фоновую работу, используя этот драгоценный камень. За документацией и дополнительной помощью обращайтесь по ссылке https://github.com/Rykian/clockwork.
вы можете использовать resque
и resque-schedular
gem для создания cron, это очень легко сделать.
Однажды мне пришлось принять такое же решение, и я действительно доволен этим решением сегодня. Используйте планировщик Resque, потому что не только отдельное Redis будет снимать нагрузку с вашей базы данных, вы также будете иметь доступ ко многим плагинам, таким как Resque-Web, который обеспечивает отличный пользовательский интерфейс. По мере развития вашей системы вы будете планировать все больше и больше задач, чтобы вы могли управлять ими из одного места.
Вероятно, лучший способ сделать это - использовать rake для написания необходимых вам задач и просто выполнить его через командную строку.
Вы можете посмотреть очень полезное видео на Railscasts
Также взгляните на эти другие ресурсы:
Я не совсем уверен, думаю, это зависит от задачи: как часто бегать, насколько сложно и сколько нужно прямого общения с проектом rails и т. Д. Я думаю, был ли «Один лучший путь» что-то сделать Не было бы так много разных способов сделать это.
На моей последней работе в проекте Rails нам нужно было создать пакетное почтовое приглашение (приглашения на опрос, а не рассылку спама), которое должно отправлять запланированные письма всякий раз, когда у сервера было время. Я думаю, что мы собирались использовать инструменты демона для запуска заданий, которые я создал.
К сожалению, у нашей компании были проблемы с деньгами, и она была «куплена» основным конкурентом, поэтому проект так и не был завершен, поэтому я не знаю, что мы в конечном итоге использовали.
Я использую скрипт для запуска cron, это лучший способ запустить cron. Вот пример для cron,
Откройте CronTab -> sudo crontab -e
И вставьте сильфонные линии:
00 00 * * * wget https: // your_host / some_API_end_point
Вот какой-то формат cron, поможет вам
::CRON FORMAT::
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.
Надеюсь, что это поможет вам :)