Jaki jest najlepszy sposób uruchamiania zaplanowanych zadań w środowisku Rails? Skrypt / biegacz? Grabie? Chciałbym uruchomić zadanie co kilka minut.
Jaki jest najlepszy sposób uruchamiania zaplanowanych zadań w środowisku Rails? Skrypt / biegacz? Grabie? Chciałbym uruchomić zadanie co kilka minut.
Odpowiedzi:
Korzystam z metody prowizji (obsługiwanej przez heroku )
Z plikiem o nazwie lib / zadania / cron.rake ..
task :cron => :environment do
puts "Pulling new requests..."
EdiListener.process_new_messages
puts "done."
end
Aby wykonać z wiersza poleceń, jest to po prostu „rake cron”. To polecenie można następnie umieścić w systemie operacyjnym cron / harmonogram zadań zgodnie z potrzebami.
Zaktualizuj to dość stare pytanie i odpowiedź! Niektóre nowe informacje:
load "#{Rails.root}/lib/tasks/cron.rake"
i rake cron
, ale otrzymałem NameError: nieokreślona zmienna lokalna lub metoda `cron 'dla main: Object
:environment
zależność. Mamy bardzo ciężką aplikację Rails, która uruchamia się długo, nasza Rake jest wywoływana co minutę i zużywa więcej zasobów, uruchamiając środowisko Rails, które wykonuje zadanie . Chciałbym mieć już uruchomione środowisko Rails, które będzie wywoływane przez crona, musi być czymś pomiędzy podejściem kontrolera a środowiskiem rake .
Korzystałem z niezwykle popularnej aplikacji Ever Ever przy projektach, które w dużej mierze polegają na zaplanowanych zadaniach i jest świetna. Daje ci fajne DSL do definiowania zaplanowanych zadań zamiast konieczności radzenia sobie z formatem crontab. Z README:
Ilekroć jest klejnot Ruby, który zapewnia jasną składnię do pisania i wdrażania zadań cron.
Przykład z pliku 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
W naszym projekcie po raz pierwszy używaliśmy klejnotów, ale napotykaliśmy pewne problemy.
Następnie przełączyliśmy się na RUFUS SCHEDULER klejnot , który okazał się bardzo łatwy i niezawodny do planowania zadań w Railsach.
Użyliśmy go do wysyłania cotygodniowych i codziennych wiadomości e-mail, a nawet do uruchamiania okresowych zadań rake lub dowolnej metody.
Kod użyty w tym jest jak:
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
Zakładając, że twoje zadania nie potrwają zbyt długo, 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ływania adresu URL tego kontrolera i działania w odpowiednich odstępach czasu. Zaletami tej metody są:
zadania skryptu / runnera i rake'u są całkowicie odpowiednie do uruchamiania jako zadania crona.
Oto jedna bardzo ważna rzecz, o której musisz pamiętać podczas uruchamiania zadań CRON. Prawdopodobnie nie zostaną wywołane z katalogu głównego aplikacji. Oznacza to, że wszystkie wymagania dotyczące plików (w przeciwieństwie do bibliotek) powinny być wykonane z wyraźną ścieżką: np. Nazwa_pliku_pliku (__ PLIK___) + „/ inny_plik”. Oznacza to również, że musisz wiedzieć, jak jawnie wywoływać je z innego katalogu :-)
Sprawdź, czy Twój kod obsługuje uruchamianie z innego katalogu za pomocą
# 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 cron prawdopodobnie nie działają tak jak Ty, więc nie polegaj na żadnym skrócie, który umieściłeś w .bashrc. Ale to tylko standardowa wskazówka crona ;-)
Problem z kiedykolwiek (i cronem) polega na tym, że przeładowuje środowisko szyny za każdym razem, gdy jest wykonywane, co jest prawdziwym problemem, gdy twoje zadania są częste lub masz dużo pracy inicjalizacyjnej. Z tego powodu miałem problemy z produkcją i muszę was ostrzec.
Rufus harmonogram robi to dla mnie ( https://github.com/jmettraux/rufus-scheduler )
Kiedy mam długie zadania do uruchomienia, używam go z opóźnieniem_job ( https://github.com/collectiveidea/delayed_job )
Mam nadzieję, że to pomoże!
Jestem wielkim fanem resque / resque planer . Możesz uruchamiać nie tylko powtarzające się zadania podobne do crona, ale także zadania w określonych momentach. Minusem jest to, że wymaga serwera Redis.
To ciekawe, że nikt nie wspomniał o Sidetiqu . Jest to miły dodatek, jeśli już używasz Sidekiq.
Sidetiq zapewnia prosty interfejs API do definiowania powtarzających się pracowników dla Sidekiq.
Job będzie wyglądał następująco:
class MyWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { hourly.minute_of_hour(15, 45) }
def perform
# do stuff ...
end
end
Oba będą działać dobrze. Zwykle używam skryptu / runnera.
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 czysto Ruby, aby to zrobić, jeśli załadujesz odpowiednie pliki konfiguracyjne do połączenia z bazą danych.
Pamiętaj, że jeśli pamięć jest cenna, skrypt / runner (lub zadanie Rake zależne od „środowiska”) załaduje całe środowisko Rails. Jeśli musisz wstawić tylko niektóre rekordy do bazy danych, zajmie to pamięć, której tak naprawdę nie musisz. Jeśli napiszesz własny skrypt, możesz tego uniknąć. Właściwie to jeszcze nie musiałem tego robić, ale rozważam to.
Użyj Craken (zadania cron rake centric)
Używam backgroundrb.
http://backgroundrb.rubyforge.org/
Używam go do uruchamiania zaplanowanych zadań, a także zadań, które trwają zbyt długo w stosunku do normalnej relacji klient / serwer.
Oto jak skonfigurowałem swoje zadania cron. Mam jeden do codziennego tworzenia kopii zapasowych bazy danych SQL (przy użyciu prowizji), a drugi do wygasania pamięci podręcznej raz w miesiącu. Każde wyjście jest rejestrowane w pliku log / cron_log. Mój crontab wygląda następująco:
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 bazy danych. 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 skonfigurowane później i używa skryptu / programu uruchamiającego do wygaśnięcia pamięci podręcznej raz w miesiącu (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}"
Chyba mógłbym wykonać kopię zapasową bazy danych w inny sposób, ale jak dotąd działa dla mnie :)
Te ścieżki do natarcia i rubin może być różna na różnych serwerach. Możesz zobaczyć, gdzie się znajdują, używając:
whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake
Używanie czegoś Sidekiq lub Resque jest znacznie bardziej niezawodnym rozwiązaniem. Obie obsługują ponawianie zadań, wyłączność z blokadą REDIS, monitorowanie i planowanie.
Pamiętaj, że Resque to martwy projekt (nie aktywnie utrzymywany), więc Sidekiq jest lepszą alternatywą. Jest również wydajniejszy: Sidekiq obsługuje kilku pracowników w jednym, wielowątkowym procesie, a Resque uruchamia każdego pracownika w osobnym procesie.
Ostatnio stworzyłem kilka miejsc pracy dla projektów, nad którymi pracuję.
Odkryłem, że klejnot Clockwork jest bardzo przydatny.
require 'clockwork'
module Clockwork
every(10.seconds, 'frequent.job')
end
Za pomocą tego klejnotu możesz nawet zaplanować pracę w tle. Aby uzyskać dokumentację i dalszą pomoc, odwiedź https://github.com/Rykian/clockwork
możesz użyć resque
iresque-schedular
klejnot do stworzenia crona, jest to bardzo łatwe do zrobienia.
Kiedyś musiałem podjąć tę samą decyzję i dziś jestem bardzo zadowolony z tej decyzji. Użyj harmonogramu resque, ponieważ nie tylko oddzielne redis usunie obciążenie z bazy danych, będziesz mieć również dostęp do wielu wtyczek, takich jak resque-web, które zapewniają świetny interfejs użytkownika. W miarę rozwoju systemu będziesz mieć coraz więcej zadań do zaplanowania, dzięki czemu będziesz w stanie kontrolować je z jednego miejsca.
Prawdopodobnie najlepszym sposobem na to jest użycie rake do napisania potrzebnych zadań i po prostu wykonanie ich za pomocą wiersza poleceń.
Bardzo przydatny film można zobaczyć podczas railscastów
Zobacz także inne zasoby:
Użyłem klejnotu zegarkowego i działa całkiem dobrze dla mnie. Istnieje również clockworkd
klejnot, który pozwala skryptowi działać jako demon.
Nie jestem do końca pewny, myślę, że zależy to od zadania: jak często uruchamiać, ile skomplikować i ile potrzebna jest bezpośrednia komunikacja z projektem szyn itp. Sądzę, że istnieje tylko „jeden najlepszy sposób”, aby coś zrobić , nie byłoby tak wielu różnych sposobów, aby to zrobić.
Podczas mojej ostatniej pracy w projekcie Rails musieliśmy stworzyć pakiet mailingowy z zaproszeniem (zaproszenia do ankiety, nie spamowanie), który powinien wysyłać planowane wiadomości e-mail, ilekroć serwer ma czas. Myślę, że zamierzaliśmy użyć narzędzi demona do uruchomienia utworzonych przeze mnie zadań prowizji.
Niestety, nasza firma miała problemy z pieniędzmi 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.
Używam skryptu do uruchamiania crona, to najlepszy sposób na uruchomienie crona. Oto przykład dla crona,
Otwórz CronTab -> sudo crontab -e
I wklej poniżej linie:
00 00 * * * wget https: // twój_host / some_API_end_point
Oto jakiś format cron, który ci pomoże
::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.
Mam nadzieję, że to ci pomoże :)