Praca cron dla rails: najlepsze praktyki?

Jaki jest najlepszy sposób uruchamiania zaplanowanych zadań w środowisku Rails? Script/runner? Rake?

Author: Philip Morton, 2008-11-13

20 answers

Używam podejścia rake (wspieranego przez heroku )

Z plikiem o nazwie lib / tasks / cron.grabie ..

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

Aby wykonać z linii poleceń, jest to po prostu "rake cron". Polecenie to można następnie umieścić w systemie operacyjnym Cron/Task scheduler zgodnie z życzeniem.

Update to dość stare pytanie i odpowiedź! Niektóre nowe info:

  • heroku cron, o którym wspomniałem, został zastąpiony przez Heroku Scheduler
  • do częstych zadań (esp. jeśli chcesz uniknąć kosztów uruchomienia środowiska Rails, moim preferowanym podejściem jest użycie crona systemowego do wywołania skryptu, który albo (a) przebije bezpieczne/prywatne API webhook, aby wywołać wymagane zadanie w tle lub (B) bezpośrednio zapyta o zadanie w wybranym systemie kolejkowym]}
 108
Author: tardate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-11 09:40:54

Używałem niezwykle popularnego kiedykolwiek w projektach, które w dużym stopniu opierają się na zaplanowanych zadaniach, i jest świetny. To daje ładny DSL do definiowania zaplanowanych zadań zamiast konieczności radzenia sobie z formatem crontab. Z README:

Ilekroć jest klejnot rubinowy, który zapewnia przejrzysta składnia do pisania i wdrażania cron jobs.

Przykład z 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
 251
Author: Jim Garvin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-16 20:01:28

Zakładając, że wykonywanie zadań nie zajmuje zbyt dużo czasu, po prostu utwórz nowy kontroler z akcją dla każdego zadania. Zaimplementuj logikę zadania jako kod kontrolera, a następnie skonfiguruj cronjob na poziomie systemu operacyjnego, który używa wget do wywołania adresu URL tego kontrolera i akcji w odpowiednich odstępach czasu. Zalety tej metody to:

  1. mieć pełny dostęp do wszystkich obiektów Rails, tak jak w normalnym kontrolerze.
  2. Może rozwijać się i testować tak, jak robisz to normalnie działania.
  3. może również wywoływać swoje zadania adhoc z prostej strony internetowej.
  4. nie zużywaj więcej pamięci uruchamiając dodatkowe procesy ruby / rails.
 16
Author: Freakent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-30 19:59:35

W naszym projekcie po raz pierwszy użyliśmy whenever gem, ale napotkaliśmy pewne problemy.

Następnie przełączyliśmy się na RUFUS SCHEDULER gem, który okazał się bardzo łatwy i niezawodny w planowaniu zadań w Rails.

Użyliśmy go do wysyłania cotygodniowych i codziennych wiadomości, a nawet do uruchamiania niektórych okresowych zadań rake lub dowolnej metody.

Użyty w tym kod wygląda następująco:

    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

Aby dowiedzieć się więcej: https://github.com/jmettraux/rufus-scheduler

 15
Author: Pankhuri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-30 07:29:20

Problem z whether (I cron) polega na tym, że przeładowuje środowisko rails za każdym razem, gdy jest wykonywane, co jest prawdziwym problemem, gdy twoje zadania są częste lub mają dużo pracy inicjalizacyjnej. Miałem z tego powodu problemy w produkcji i muszę cię ostrzec.

Rufus scheduler robi to za mnie ( https://github.com/jmettraux/rufus-scheduler )

Kiedy mam długie zadania do uruchomienia, używam go z delayed_job ( https://github.com/collectiveidea/delayed_job )

Mam nadzieję, że to pomoże!

 10
Author: Abdo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-21 22:04:17

Jestem wielkim fanem resque/resque scheduler . Możesz nie tylko uruchamiać powtarzające się zadania podobne do crona, ale także zadania w określonych godzinach. Minusem jest to, że wymaga serwera Redis.

 10
Author: Tyler Morgan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-11 04:43:25

Zadania Script/runner i rake doskonale nadają się do uruchamiania jako Zadania cron.

Oto jedna bardzo ważna rzecz, którą musisz pamiętać podczas uruchamiania zadań cron. Prawdopodobnie nie zostaną wywołane z katalogu głównego aplikacji. Oznacza to, że wszystkie twoje wymagania dla plików (w przeciwieństwie do bibliotek) powinny być wykonane z jawną ścieżką: np. File.dirname (__FILE__) + "/ other_file". Oznacza to również, że musisz wiedzieć, jak jawnie wywołać je z innego katalogu: -)

Sprawdź czy Twój kod obsługuje uruchamianie z innego katalogu z

# 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

Ponadto, zadania crona prawdopodobnie nie działają tak jak ty, więc nie polegaj na żadnym skrócie, który wstawiłeś .bashrc. Ale to tylko standardowa porada crona; -)

 9
Author: webmat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-13 14:43:53

Oba będą działać dobrze. Zazwyczaj używam script / runner.

Oto przykład:

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

Możesz również napisać skrypt Pure-Ruby, jeśli załadujesz odpowiednie pliki konfiguracyjne, aby połączyć się z bazą danych.

Należy pamiętać o tym, że script / runner (lub zadanie Rake, które zależy od 'environment') załaduje całe środowisko Rails. Jeśli musisz tylko wstawić kilka rekordów do bazy danych, użyje to Pamięci, której tak naprawdę nie masz za. Jeśli napiszesz własny skrypt, możesz tego uniknąć. Jeszcze nie musiałem tego robić, ale rozważam to.

 8
Author: Luke Francl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-14 18:19:17

Use Craken (rake centric cron jobs)

 8
Author: Thibaut Barrère,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-28 21:11:22

Ciekawe, że nikt nie wspomniał o Sidetiq . Jest to miły dodatek, jeśli już używasz Sidekiq.

Sidetiq zapewnia proste API do definiowania powtarzających się pracowników dla Sidekiq.

Praca będzie wyglądała tak:

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

  recurrence { hourly.minute_of_hour(15, 45) }

  def perform
    # do stuff ...
  end
end
 8
Author: AlexParamonov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-14 22:05:57

Używam backgroundrb.

Http://backgroundrb.rubyforge.org/

Używam go do uruchamiania zaplanowanych zadań, jak również zadań, które trwają zbyt długo dla normalnej relacji klient / serwer.

 5
Author: salt.racer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-11-13 00:12:04

Oto jak skonfigurowałem Moje zadania cron. Mam jeden do wykonywania codziennych kopii zapasowych bazy danych SQL (za pomocą rake), a drugi do wygaśnięcia cache raz w miesiącu. Każde wyjście jest rejestrowane w pliku log/cron_log. Mój crontab wygląda tak:

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

Pierwsze zadanie cron wykonuje codzienne kopie zapasowe db. Zawartość cron_tasks jest następująca:

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

Drugie zadanie zostało ustawione później i używa script/runner do wygaśnięcia pamięci podręcznej raz w miesiącu (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}"

I guess I could backup baza jakoś inaczej ale jak na razie działa u mnie:)

Ścieżki do rake i ruby mogą się różnić na różnych serwerach. Możesz zobaczyć, gdzie są, używając:

whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake
 3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-26 15:54:15

Używanie czegoś Sidekiq lub Resque jest o wiele bardziej solidnym rozwiązaniem. Obie obsługują ponowną próbę zadań, wyłączność z blokadą REDIS, monitorowanie i planowanie.

Pamiętaj, że Resque jest martwym projektem (nie utrzymywanym aktywnie), więc Sidekiq jest o wiele lepszą alternatywą. Jest również bardziej wydajny: Sidekiq uruchamia kilku pracowników w jednym, wielowątkowym procesie, podczas gdy Resque uruchamia każdego pracownika w osobnym procesie.

 3
Author: jaysqrd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-16 18:23:08

Ostatnio stworzyłem kilka zadań cron dla projektów, nad którymi pracowałem.

Odkryłem, że klejnot Clockwork jest bardzo przydatny.

require 'clockwork'

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

Możesz nawet zaplanować pracę w tle za pomocą tego klejnotu. Aby uzyskać dokumentację i dalszą pomoc, zapoznaj się z https://github.com/Rykian/clockwork

 3
Author: Vipul Lawande,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-07 14:42:23

Kiedyś musiałem podjąć tę samą decyzję i jestem bardzo zadowolony z tej decyzji dzisiaj. Użyj Resque scheduler ponieważ nie tylko oddzielny redis usunie obciążenie z twojego db, będziesz miał również dostęp do wielu wtyczek, takich jak resque-web, który zapewnia świetny interfejs użytkownika. W miarę rozwoju systemu będziesz miał coraz więcej zadań do zaplanowania, dzięki czemu będziesz mógł kontrolować je z jednego miejsca.

 2
Author: Caner Çakmak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-01 20:07:14

Możesz użyć Resque i resque-shheduler gem do tworzenia cronów, jest to bardzo łatwe do zrobienia.

Https://github.com/resque/resque

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

 2
Author: Israel Barba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-26 18:10:29

Prawdopodobnie najlepszym sposobem na to jest użycie rake do pisania zadań, których potrzebujesz i po prostu wykonaj je za pomocą wiersza poleceń.

Możesz zobaczyć bardzo pomocne wideo na railscasts

Zobacz też inne zasoby:

 1
Author: Adrià Cidre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 20:17:35

Użyłemclockwork gem i działa całkiem dobrze dla mnie. Istnieje również gem clockworkd, który pozwala skryptowi uruchamiać się jako demon.

 1
Author: nnattawat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-03 02:33:28

Nie jestem do końca pewien, chyba zależy to od zadania: jak często uruchomić, jak bardzo skomplikowana i jak bardzo potrzebna jest bezpośrednia komunikacja z projektem rails itp. Myślę, że gdyby był tylko "jeden najlepszy sposób", aby coś zrobić, nie byłoby tak wiele różnych sposobów, aby to zrobić.

W mojej ostatniej pracy w projekcie Rails, musieliśmy zrobić Mailer zaproszeń wsadowych (zaproszenia ankietowe, nie spamowanie), który powinien wysyłać zaplanowane maile, gdy serwer miał czas. Myślę, że byliśmy użyję daemon tools do uruchomienia utworzonych przeze mnie zadań rake.

Niestety, nasza firma miała problemy finansowe i została "kupiona" przez głównego rywala, więc projekt nigdy nie został ukończony, więc nie wiem, co byśmy w końcu wykorzystali.

 0
Author: Stein G. Strindhaug,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-22 14:52:12

Używam skryptu do uruchamiania crona, to jest najlepszy sposób na uruchomienie crona. Oto przykład dla cron,

Otwórz CronTab - > sudo crontab-e

I wklej poniżej linie:

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

Oto jakiś format cron, który Ci pomoże

::CRON FORMAT::

tabela formatu cron

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. 

Mam nadzieję, że to ci pomoże:)

 0
Author: Ami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-21 10:27:45