Во многих случаях работа cron - это неприятный запах. Лучше написать планировщик через sidekiq / resque (или другой фоновый работник) или написать демон (менее функциональный и контролируемый). У заданий Cron есть как минимум несколько плохих вещей: 1) блокировка одного экземпляра - это боль; 2) мониторинг не может быть осуществлен легко; 3) обработка исключений должна быть снова написана вручную; 4) не легко перезапустить; 5) все вышеперечисленные вопросы легко решаются фоновыми работниками.
Дмитрий Полушкин
Ответы:
110
Я использую рейк-подход (как поддерживает heroku )
С файлом с именем lib / tasks / cron.rake ..
task :cron =>:environment do
puts "Pulling new requests..."EdiListener.process_new_messages
puts "done."end
Чтобы выполнить из командной строки, это просто "rake cron". Эта команда затем может быть помещена в cron / планировщик задач операционной системы по желанию.
Обновите это довольно старый вопрос и ответ! Некоторая новая информация:
сервис Heroku Cron, на который я ссылался, был заменен Heroku Scheduler
для частых задач (особенно там, где вы хотите избежать затрат на запуск среды Rails), я предпочитаю использовать системный cron для вызова скрипта, который либо (a) выдает API защищенного / частного webhook для вызова необходимой задачи в фоновом режиме или (б) поставить в очередь задачу в выбранной вами системе очередей
Какой должна быть запись cron для этого случая, чтобы ОС знала правильный путь к задаче rake?
Джридиоко
13
NB: в эти дни я использую всякий раз (см. Ответ Джима Гарвина), но необработанная запись cron для запуска задачи rake будет выглядеть примерно так: 30 4 * * * / bin / bash -l -c 'cd / opt / railsapp && RAILS_ENV = производственные грабли cron --silent '
tardate
1
Как вы называете это с консоли? Я сделал load "#{Rails.root}/lib/tasks/cron.rake"и rake cron, но получил NameError: неопределенная локальная переменная или метод `cron 'для main: Object
B Seven
3
Проблема этого подхода заключается в :environmentзависимости. У нас очень тяжелое Rails-приложение, которое требует много времени для запуска, наш Rake вызывается каждую минуту и потребляет больше ресурсов для запуска среды Rails, которая выполняет задачу . Я хотел бы, чтобы уже запущенная среда Rails вызывалась через cron, должна быть что-то среднее между подходом контроллера и средой rake .
fguillen
Какова продолжительность этого задания? Я использую условие if. Я хочу знать, как регулярно это выполняется. Я не могу найти никакой информации об этом на сайте heroku.
Шубхам Чаудхари
254
Я использовал чрезвычайно популярный проект всякий раз, когда он сильно зависит от запланированных задач, и это здорово. Это дает вам хороший DSL для определения ваших запланированных задач вместо того, чтобы иметь дело с форматом crontab. Из README:
Всякий раз, когда это Ruby-гем, который предоставляет четкий синтаксис для написания и развертывания заданий cron.
Пример из README:
every 3.hoursdo
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
Если он запускается каждую минуту, среда будет перезапускаться каждый раз, что может быть дорогостоящим. Похоже, что github.com/ssoroka/scheduler_daemon избегает этого.
Лулалала
3
+1 за сохранение конфигурации cron в вашей системе контроля версий
brittohalloran
3
Я думаю, что это лучшее решение. Если вы используете рельсы, я думаю, что лучше написать все в рельсах. При таком подходе вы также можете забыть о задаче cron при смене серверов, она перемещается вместе с приложением.
Адриан Маттео
Существует отличный Railscast о том, когда это действительно полезно (более старая бесплатная версия также доступна ).
aceofbassgreg
@ Тони, Всякий раз, когда это в основном предметно-ориентированный язык для написания заданий cron. Он компилируется в обычный синтаксис cron на вашем сервере rails, и cron выполняет заданные вами задания (обычно через rails runner).
Грег
19
В нашем проекте мы впервые использовали gem, но столкнулись с некоторыми проблемами.
Затем мы переключились на гем RUFUS SCHEDULER , который оказался очень простым и надежным для планирования задач в Rails.
Мы использовали его для отправки еженедельных и ежедневных писем, и даже для запуска некоторых периодических рейковых задач или любым другим способом.
Код, используемый в этом как:
require'rufus-scheduler'
scheduler =Rufus::Scheduler.new
scheduler.in'10d'do# do something in 10 daysend
scheduler.at '2030/12/12 23:30:00'do# do something at a given point in timeend
scheduler.every '3h'do# do something every 3 hoursend
scheduler.cron '5 0 * * *'do# do something every day, five minutes after midnight# (see "man 5 crontab" in your terminal)end
На rufus, так как я использовал его как для простых проектов ruby, так и для приложений full rails.
Пауло Фидальго
8
Не могли бы вы немного конкретнее рассказать о проблемах, с которыми вы столкнулись?
Герцог
самый великий ответ
Дарлан Дитрих
17
Предполагая, что выполнение ваших задач не занимает много времени, просто создайте новый контроллер с действием для каждой задачи. Реализуйте логику задачи в виде кода контроллера, затем настройте cronjob на уровне ОС, который использует wget для вызова URL-адреса этого контроллера и действия в соответствующие промежутки времени. Преимуществами этого метода являются вы:
Иметь полный доступ ко всем вашим объектам Rails, как в обычном контроллере.
Может развиваться и тестировать так же, как вы делаете обычные действия.
Может также вызвать ваши задачи adhoc с простой веб-страницы.
Не используйте больше памяти, запуская дополнительные процессы ruby / rails.
Как запретить другим доступ к этой задаче? Если задача, принимающая процессор и вызывающая его часто, вызовет проблемы.
sarunw
44
Я знаю, что это было некоторое время назад, но это определенно не лучший способ делать работу cron больше. Зачем идти через веб-интерфейс, нарушая то, что на самом деле представляет интерфейс, когда есть много других способов получить доступ к среде Rails?
Матчу
6
Квалификация «при условии, что ваши задачи не занимают слишком много времени» кажется огромной. Не лучше ли использовать более общий подход, и не только в тех случаях, когда задачи выполняются очень быстро? Таким образом, вы не будете постоянно переоценивать необходимость переписывания той или иной задачи с использованием другого подхода.
иконоборчество
77
Этот старый вопрос является лучшим результатом Google для "rails cron". Этот ответ далеко не лучший подход. Пожалуйста, смотрите другие ответы для более вменяемых предложений.
Джим Гарвин
2
Не лучший способ. У вас есть много других способов получить доступ к Rails env через задание cron без вызова службы REST. Подход с рейком определенно лучше
Shine
10
Задачи 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 ;-)
Вы можете запустить задание как любой пользователь (просто установите запись crontab для пользователя, которого вы хотите), но вы правы, что сценарии профиля и входа в систему не будут запускаться, и вы не запустите их в своем домашнем каталоге. Поэтому обычно команду запускают с «cd», как показано в комментарии @ luke-franci
Том Уилсон
10
Проблема с всякий раз, когда (и cron) перезагружается среда rails каждый раз, когда она выполняется, что является реальной проблемой, когда ваши задачи выполняются часто или у вас много работы по инициализации. У меня были проблемы с производством из-за этого, и я должен предупредить вас.
Я большой поклонник Resque / Resque Scheduler . Вы можете запускать повторяющиеся задачи, похожие на cron, но и задачи в определенное время. Недостатком является то, что для этого требуется сервер Redis.
Оба будут работать нормально. Я обычно использую скрипт / бегун.
Вот пример:
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. Если вам нужно только вставить некоторые записи в базу данных, это будет использовать память, которая вам на самом деле не нужна. Если вы пишете свой собственный сценарий, вы можете избежать этого. На самом деле мне еще не нужно было это делать, но я обдумываю это.
Вот как я настроил свои задачи 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 crontab01*** cd /home/lenart/izziv. whiskas.si/current;/bin/sh cron_tasks >> log/cron_log 2>&1001** 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):
Использование чего-то Sidekiq или Resque является гораздо более надежным решением. Они оба поддерживают повторные задания, эксклюзивность с блокировкой REDIS, мониторинг и планирование.
Имейте в виду, что Resque - это мертвый проект (не активно поддерживаемый), поэтому Sidekiq - лучшая альтернатива. Он также более производительный: Sidekiq запускает несколько рабочих в одном многопоточном процессе, а Resque запускает каждого рабочего в отдельном процессе.
Это правильный ответ. Многие могут забыть о приятных функциях, которые предоставляет sidekiq или resque, например, веб-интерфейс для мониторинга происходящего: количество запущенных, сбойных или запланированных заданий, простой перезапуск, блокировка для уникальных работников, регулирование и ограничение и т. Д.
Дмитрий Полушкин
3
Недавно я создал несколько рабочих мест для проектов, над которыми я работал.
Я обнаружил, что драгоценный камень Заводной очень полезен.
Вы можете даже запланировать свою фоновую работу, используя этот драгоценный камень. За документацией и дополнительной помощью обращайтесь по ссылке https://github.com/Rykian/clockwork.
Однажды мне пришлось принять такое же решение, и я действительно доволен этим решением сегодня. Используйте планировщик Resque, потому что не только отдельное Redis будет снимать нагрузку с вашей базы данных, вы также будете иметь доступ ко многим плагинам, таким как Resque-Web, который обеспечивает отличный пользовательский интерфейс. По мере развития вашей системы вы будете планировать все больше и больше задач, чтобы вы могли управлять ими из одного места.
Я безуспешно пытался использовать синтаксис в этом уроке. Задача не была выполнена.
ТАСС
1
Я использовал заводной драгоценный камень, и он довольно хорошо работает для меня. Существует также clockworkdгем, который позволяет скрипту запускаться как демон.
Я не совсем уверен, думаю, это зависит от задачи: как часто бегать, насколько сложно и сколько нужно прямого общения с проектом rails и т. Д. Я думаю, был ли «Один лучший путь» что-то сделать Не было бы так много разных способов сделать это.
На моей последней работе в проекте Rails нам нужно было создать пакетное почтовое приглашение (приглашения на опрос, а не рассылку спама), которое должно отправлять запланированные письма всякий раз, когда у сервера было время. Я думаю, что мы собирались использовать инструменты демона для запуска заданий, которые я создал.
К сожалению, у нашей компании были проблемы с деньгами, и она была «куплена» основным конкурентом, поэтому проект так и не был завершен, поэтому я не знаю, что мы в конечном итоге использовали.
ExamplesOf crontab Entries15621*/home/melissa/backup.sh
Run the shell script /home/melissa/backup.sh on January2 at 6:15 A.M.150602Jan*/home/melissa/backup.sh
Sameas the above entry.Zeroes can be added at the beginning of a number for legibility, without changing their value.09-18***/home/carl/hourly-archive.sh
Run/home/carl/hourly-archive.sh every hour, on the hour,from9 A.M. through 6 P.M., every day.09,18**Mon/home/wendy/script.sh
Run/home/wendy/script.sh every Monday, at 9 A.M.and6 P.M.3022**Mon,Tue,Wed,Thu,Fri/usr/local/bin/backup
Run/usr/local/bin/backup at 10:30 P.M., every weekday.
Ответы:
Я использую рейк-подход (как поддерживает heroku )
С файлом с именем lib / tasks / cron.rake ..
Чтобы выполнить из командной строки, это просто "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:
Пример из README:
источник
В нашем проекте мы впервые использовали gem, но столкнулись с некоторыми проблемами.
Затем мы переключились на гем RUFUS SCHEDULER , который оказался очень простым и надежным для планирования задач в Rails.
Мы использовали его для отправки еженедельных и ежедневных писем, и даже для запуска некоторых периодических рейковых задач или любым другим способом.
Код, используемый в этом как:
Чтобы узнать больше: https://github.com/jmettraux/rufus-scheduler
источник
Предполагая, что выполнение ваших задач не занимает много времени, просто создайте новый контроллер с действием для каждой задачи. Реализуйте логику задачи в виде кода контроллера, затем настройте cronjob на уровне ОС, который использует wget для вызова URL-адреса этого контроллера и действия в соответствующие промежутки времени. Преимуществами этого метода являются вы:
источник
Задачи script / runner и rake прекрасно подходят для выполнения заданий cron.
Вот одна очень важная вещь, которую вы должны помнить при запуске заданий cron. Они, вероятно, не будут вызываться из корневого каталога вашего приложения. Это означает, что все ваши требования к файлам (в отличие от библиотек) должны выполняться с явным путем: например, File.dirname (__ FILE__) + "/ other_file". Это также означает, что вы должны знать, как явно вызывать их из другого каталога :-)
Проверьте, поддерживает ли ваш код запуск из другого каталога с
Кроме того, задания 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.
Работа будет выглядеть так:
источник
Оба будут работать нормально. Я обычно использую скрипт / бегун.
Вот пример:
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 выглядит так:
Первая задача cron делает ежедневные резервные копии БД. Содержимое cron_tasks следующее:
Вторая задача была настроена позже и использует скрипт / runner для истечения срока действия кэша один раз в месяц (lib / month_cron.rb):
Я думаю, я мог бы сделать резервную копию базы данных другим способом, но пока это работает для меня :)
На пути грабли и рубин может варьироваться на разных серверах. Вы можете увидеть, где они находятся, используя:
источник
Использование чего-то Sidekiq или Resque является гораздо более надежным решением. Они оба поддерживают повторные задания, эксклюзивность с блокировкой REDIS, мониторинг и планирование.
Имейте в виду, что Resque - это мертвый проект (не активно поддерживаемый), поэтому Sidekiq - лучшая альтернатива. Он также более производительный: Sidekiq запускает несколько рабочих в одном многопоточном процессе, а Resque запускает каждого рабочего в отдельном процессе.
источник
Недавно я создал несколько рабочих мест для проектов, над которыми я работал.
Я обнаружил, что драгоценный камень Заводной очень полезен.
Вы можете даже запланировать свою фоновую работу, используя этот драгоценный камень. За документацией и дополнительной помощью обращайтесь по ссылке https://github.com/Rykian/clockwork.
источник
вы можете использовать
resque
иresque-schedular
gem для создания cron, это очень легко сделать.https://github.com/resque/resque
https://github.com/resque/resque-scheduler
источник
Однажды мне пришлось принять такое же решение, и я действительно доволен этим решением сегодня. Используйте планировщик Resque, потому что не только отдельное Redis будет снимать нагрузку с вашей базы данных, вы также будете иметь доступ ко многим плагинам, таким как Resque-Web, который обеспечивает отличный пользовательский интерфейс. По мере развития вашей системы вы будете планировать все больше и больше задач, чтобы вы могли управлять ими из одного места.
источник
Вероятно, лучший способ сделать это - использовать rake для написания необходимых вам задач и просто выполнить его через командную строку.
Вы можете посмотреть очень полезное видео на Railscasts
Также взгляните на эти другие ресурсы:
источник
Я использовал заводной драгоценный камень, и он довольно хорошо работает для меня. Существует также
clockworkd
гем, который позволяет скрипту запускаться как демон.источник
Я не совсем уверен, думаю, это зависит от задачи: как часто бегать, насколько сложно и сколько нужно прямого общения с проектом rails и т. Д. Я думаю, был ли «Один лучший путь» что-то сделать Не было бы так много разных способов сделать это.
На моей последней работе в проекте Rails нам нужно было создать пакетное почтовое приглашение (приглашения на опрос, а не рассылку спама), которое должно отправлять запланированные письма всякий раз, когда у сервера было время. Я думаю, что мы собирались использовать инструменты демона для запуска заданий, которые я создал.
К сожалению, у нашей компании были проблемы с деньгами, и она была «куплена» основным конкурентом, поэтому проект так и не был завершен, поэтому я не знаю, что мы в конечном итоге использовали.
источник
Я использую скрипт для запуска cron, это лучший способ запустить cron. Вот пример для cron,
Откройте CronTab -> sudo crontab -e
И вставьте сильфонные линии:
00 00 * * * wget https: // your_host / some_API_end_point
Вот какой-то формат cron, поможет вам
Надеюсь, что это поможет вам :)
источник