it-swarm.com.de

Ein Cron-Job für Rails: Best Practices?

Was ist der beste Weg, um geplante Aufgaben in einer Rails-Umgebung auszuführen? Drehbuch/Läufer Rechen?

291
jes5199

Ich verwende den Rake-Ansatz (unterstützt von heroku )

Mit einer Datei namens lib/task/cron.rake ..

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

Von der Kommandozeile aus auszuführen, ist dies nur "Rake Cron". Dieser Befehl kann dann wie gewünscht in den cron/task-Scheduler des Betriebssystems gestellt werden.

Update das ist schon eine alte Frage und Antwort! Einige neue Infos:

  • der heroku cron-Service, auf den ich mich bezogen habe, wurde seitdem durch Heroku Scheduler ersetzt
  • für häufige Aufgaben (vor allem, wenn Sie die Startkosten der Rails-Umgebung vermeiden möchten) ist es mein bevorzugter Ansatz, mit system cron ein Skript aufzurufen, das entweder (a) eine sichere/private Webhook-API stößt, um die erforderliche Aufgabe im Hintergrund aufzurufen oder (b) eine Aufgabe direkt in Ihr Warteschlangensystem Ihrer Wahl aufnehmen 
108
tardate

Ich habe das extrem beliebte Whenever für Projekte verwendet, die stark von geplanten Aufgaben abhängig sind, und es ist großartig. Es gibt Ihnen ein Nice DSL, um Ihre geplanten Aufgaben zu definieren, anstatt sich mit dem Crontab-Format zu befassen. Aus der README:

Wann ist ein Ruby-Edelstein, der eine klare Syntax zum Schreiben und Bereitstellen von Zeitgesteuerte Aufgaben.

Beispiel aus der 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
252
Jim Garvin

Wenn Sie davon ausgehen, dass Ihre Aufgaben nicht zu lange dauern, erstellen Sie einfach einen neuen Controller mit einer Aktion für jede Aufgabe. Implementieren Sie die Logik der Task als Controller-Code. Richten Sie dann auf Betriebssystemebene einen Cronjob ein, der die URL dieses Controllers mithilfe von wget in den entsprechenden Zeitintervallen aufruft. Die Vorteile dieser Methode sind Sie:

  1. Greifen Sie wie in einem normalen Controller auf alle Ihre Rails-Objekte zu.
  2. Kann sich wie normale Aktionen entwickeln und testen. 
  3. Kann Ihre Aufgaben auch adhoc von einer einfachen Webseite aus aufrufen.
  4. Verbrauchen Sie keinen Speicher mehr, indem Sie zusätzliche Ruby/Rails-Prozesse starten.
17
Freakent

In unserem Projekt haben wir zuerst immer Juwel eingesetzt, hatten aber einige Probleme.

Wir haben dann auf RUFUS SCHEDULER gem umgestellt, was sich als sehr einfach und zuverlässig für die Planung von Aufgaben in Rails herausstellte.

Wir haben es zum Versenden von wöchentlichen und täglichen E-Mails und sogar zum Ausführen einiger periodischer Rake-Aufgaben oder anderer Methoden verwendet.

Der hier verwendete Code ist wie folgt:

    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

Um mehr zu erfahren: https://github.com/jmettraux/rufus-scheduler

15
Pankhuri

Ich bin ein großer Fan von resque / resque Scheduler . Sie können nicht nur wiederholende cron-ähnliche Aufgaben ausführen, sondern auch Aufgaben zu bestimmten Zeiten. Der Nachteil ist, es erfordert einen Redis-Server.

10
Tyler Morgan

Das Problem bei always (und cron) ist, dass die Rails-Umgebung bei jeder Ausführung neu geladen wird. Dies ist ein echtes Problem, wenn Ihre Aufgaben häufig ausgeführt werden oder eine Menge Initialisierungsarbeit erforderlich ist. Ich hatte aus diesem Grund Probleme in der Produktion und muss Sie warnen.

Rufus Scheduler erledigt das für mich ( https://github.com/jmettraux/rufus-scheduler )

Wenn ich lange Jobs habe, benutze ich es mit delayed_job ( https://github.com/collectiveidea/delayed_job )

Ich hoffe das hilft!

10
Abdo

Interessant ist, dass niemand das Sidetiq ..__ angesprochen hat.

Sidetiq bietet eine einfache API zur Definition wiederkehrender Worker für Sidekiq.

Job wird so aussehen:

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

  recurrence { hourly.minute_of_hour(15, 45) }

  def perform
    # do stuff ...
  end
end
9
AlexParamonov

script-/Runner- und Rake-Aufgaben eignen sich hervorragend als Cron-Jobs.

Hier ist eine sehr wichtige Sache, die Sie beim Ausführen von Cron-Jobs beachten müssen. Sie werden wahrscheinlich nicht aus dem Stammverzeichnis Ihrer App aufgerufen. Dies bedeutet, dass alle Ihre Anforderungen an Dateien (im Gegensatz zu Bibliotheken) mit dem expliziten Pfad erfolgen sollten: z. File.dirname (__ FILE__) + "/ other_file". Das bedeutet auch, dass Sie wissen müssen, wie Sie sie explizit von einem anderen Verzeichnis aus aufrufen müssen :-)

Prüfen Sie, ob Ihr Code die Ausführung mit einem anderen Verzeichnis unterstützt 

# 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

Außerdem werden Cron-Jobs wahrscheinlich nicht als Sie ausgeführt, also hängen Sie nicht von einer Verknüpfung ab, die Sie in .bashrc eingeben. Das ist aber nur ein Standard-Cron-Tipp ;-)

9
webmat

Beides wird gut funktionieren. Ich benutze normalerweise Skript/Läufer. 

Hier ist ein Beispiel:

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

Sie können auch ein Pure-Ruby-Skript schreiben, wenn Sie die richtigen Konfigurationsdateien laden, um eine Verbindung zu Ihrer Datenbank herzustellen.

Wenn der Speicher wertvoll ist, sollten Sie daran denken, dass Skript/Runner (oder eine Rake-Task, die von der Umgebung abhängig ist) die gesamte Rails-Umgebung laden. Wenn Sie nur einige Datensätze in die Datenbank einfügen müssen, wird Speicher verwendet, den Sie nicht unbedingt benötigen. Wenn Sie Ihr eigenes Skript schreiben, können Sie dies vermeiden. Ich brauchte das eigentlich noch nicht, aber ich denke darüber nach.

8
Luke Francl

Verwenden Sie Craken (Rechen zentrische Cron-Jobs)

8

Ich benutze backgroundrb.

http://backgroundrb.rubyforge.org/

Ich benutze es, um geplante Tasks sowie Tasks auszuführen, die für die normale Client/Server-Beziehung zu lange dauern.

5
salt.racer

Die Verwendung von Sidekiq oder Resque ist eine weitaus robustere Lösung. Beide unterstützen Wiederholungsaufträge, Exklusivität mit einer REDIS-Sperre, Überwachung und Zeitplanung.

Denken Sie daran, dass Resque ein totes Projekt ist (nicht aktiv verwaltet), sodass Sidekiq eine bessere Alternative ist. Es ist auch leistungsfähiger: Sidekiq führt mehrere Worker in einem einzigen Multithread-Prozess aus, während Resque jeden Worker in einem separaten Prozess ausführt.

3
jaysqrd

Ich habe kürzlich einige Cron-Jobs für die Projekte geschaffen, an denen ich gearbeitet habe.

Ich fand das Juwel Clockwork sehr nützlich.

require 'clockwork'

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

Sie können sogar Ihren Hintergrundjob mit diesem Edelstein einplanen . Dokumentation und weitere Hilfe finden Sie unter https://github.com/Rykian/clockwork

3
Vipul Lawande

So habe ich meine Cron-Aufgaben eingerichtet. Ich habe eine, die täglich Sicherungskopien der SQL-Datenbank (mit Rake) erstellt, und eine andere, um den Cache einmal im Monat ablaufen zu lassen. Jede Ausgabe wird in einer Datei log/cron_log protokolliert. Mein Crontab sieht so aus:

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

Die erste Cron-Aufgabe erstellt tägliche Db-Sicherungen. Der Inhalt von cron_tasks ist folgender:

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

Die zweite Aufgabe wurde später eingerichtet und läuft einmal pro Monat mit einem Script/Runner ab (lib/monatlich_cron.rb):

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

Ich vermute, ich könnte Datenbank auf andere Weise sichern, aber bisher funktioniert es für mich :)

Die Pfade pfade und Ruby können auf verschiedenen Servern variieren. Sie können sehen, wo sie sind, indem Sie Folgendes verwenden:

whereis Ruby # -> Ruby: /usr/local/bin/Ruby
whereis rake # -> rake: /usr/local/bin/rake
3
Lenart

Einmal musste ich dieselbe Entscheidung treffen und bin heute mit dieser Entscheidung sehr zufrieden. Verwenden Sie resque scheduler da nicht nur ein separater Redis die Last aus Ihrer Datenbank nimmt, haben Sie auch Zugriff auf viele Plugins wie resque-web, die eine hervorragende Benutzeroberfläche bieten. Während sich Ihr System entwickelt, müssen Sie immer mehr Aufgaben planen, damit Sie sie von einem einzigen Ort aus steuern können. 

2
Caner Çakmak

sie können Resque- und Resque-Shheduler-Edelsteine ​​zum Erstellen von crons verwenden. Dies ist sehr einfach durchzuführen.

https://github.com/resque/resque

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

2
Israel Barba

Ich habe clockwork gem verwendet und es funktioniert ziemlich gut für mich. Es gibt auch clockworkd gem, mit dem ein Skript als Dämon ausgeführt werden kann.

1
nnattawat

Der beste Weg, dies zu tun, ist wahrscheinlich die Verwendung von Rake, um die benötigten Aufgaben zu schreiben und einfach über die Befehlszeile auszuführen.

Sie können ein sehr hilfreiches Video bei Schienenübertragungen sehen

Schauen Sie sich auch diese anderen Ressourcen an:

1
Adrià Cidre

Ich bin mir nicht wirklich sicher, ich denke, es hängt von der Aufgabe ab: wie oft ausgeführt wird, wie kompliziert und wie viel direkte Kommunikation mit dem Rails-Projekt erforderlich ist usw. Ich denke, es gab nur "One Best Way" um etwas zu tun, gäbe es nicht so viele verschiedene Möglichkeiten.

Bei meinem letzten Job in einem Rails-Projekt mussten wir einen Batcheinladungs-Mailer erstellen (Umfrageeinladungen, kein Spam), der die geplanten E-Mails senden sollte, sobald der Server Zeit hatte. Ich denke, wir würden daemon tools verwenden, um die von mir erstellten Rake-Tasks auszuführen. 

Leider hatte unsere Firma einige Probleme mit dem Geld und wurde vom Hauptkonkurrenten "gekauft", so dass das Projekt nie abgeschlossen wurde. Ich weiß also nicht, was wir letztendlich gebraucht hätten.

0

Ich verwende cron, um cron auszuführen. Dies ist der beste Weg, um cron auszuführen .. Hier ein Beispiel für cron

Öffnen Sie CronTab -> Sudo crontab -e

Und füge Faltenlinien ein:

00 00 * * * wget https: // Ihr_Host/irgendein_API_end_point

Hier ist ein Cron-Format, das dir helfen wird

::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. 

Hoffe das hilft dir :)

0
Ami