Domanda

Qual è il modo migliore per eseguire attività pianificate in un ambiente Rails? Script / runner? Rake?

È stato utile?

Soluzione

Sto usando l'approccio rake (come supportato da heroku )

Con un file chiamato lib / task / cron.rake ..

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

Per eseguire dalla riga di comando, questo è solo " rake cron " ;. Questo comando può quindi essere inserito nel cron / task scheduler del sistema operativo come desiderato.

Aggiorna questa è una domanda e una risposta piuttosto vecchie! Alcune nuove informazioni:

  • il servizio di cronologia di heroku a cui ho fatto riferimento è stato sostituito da Heroku Scheduler
  • per attività frequenti (specialmente dove si desidera evitare i costi di avvio dell'ambiente Rails) il mio approccio preferito è quello di utilizzare il cron di sistema per chiamare uno script che (a) attiverà un'API webhook sicura / privata per richiamare l'attività richiesta in background o (b) accoda direttamente un'attività sul sistema di accodamento scelto

Altri suggerimenti

Ho usato il estremamente popolare Ogni volta su progetti che dipendono fortemente da attività pianificate, ed è fantastico . Ti dà un bel DSL per definire le attività pianificate invece di dover gestire il formato crontab. Dal README:

  

Ogni volta che è una gemma di rubino che fornisce a   sintassi chiara per la scrittura e la distribuzione   cron jobs.

Esempio dal 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

Nel nostro progetto abbiamo usato per la prima volta ogni volta gemma, ma abbiamo affrontato alcuni problemi.

Siamo quindi passati a RUFUS SCHEDULER gemma, che si è rivelato essere molto semplice e affidabile per la pianificazione delle attività in Rails.

Lo abbiamo usato per inviare settimanalmente & amp; posta giornaliera e anche per l'esecuzione di alcune attività di rake periodiche o di qualsiasi metodo.

Il codice utilizzato in questo è simile a:

    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

Per saperne di più: https://github.com/jmettraux/rufus-scheduler

Supponendo che le attività non richiedano troppo tempo per il completamento, basta creare un nuovo controller con un'azione per ogni attività. Implementare la logica dell'attività come codice controller, quindi impostare un cronjob a livello di sistema operativo che utilizza wget per richiamare l'URL di questo controller e agire agli intervalli di tempo appropriati. I vantaggi di questo metodo sei:

  1. Avere pieno accesso a tutti gli oggetti Rails come in un normale controller.
  2. Può svilupparsi e testare esattamente come fai con le normali azioni.
  3. Può anche invocare le attività ad hoc da una semplice pagina Web.
  4. Non consumare più memoria attivando ulteriori processi ruby ??/ rails.

Il problema con quando (e cron) è che ricarica l'ambiente delle rotaie ogni volta che viene eseguito, il che è un vero problema quando le tue attività sono frequenti o hanno molto lavoro di inizializzazione da fare. Ho avuto problemi di produzione a causa di ciò e devo avvisarti.

Lo strumento di pianificazione Rufus lo fa per me ( https://github.com/jmettraux/rufus-scheduler )

Quando ho lunghi lavori da eseguire, lo uso con delayed_job ( https://github.com/collectiveidea/delayed_job )

Spero che questo aiuti!

Sono un grande fan di resque / resque scheduler . Puoi non solo eseguire attività simili a cron ripetute ma anche attività in momenti specifici. L'aspetto negativo è che richiede un server Redis.

le attività di script / runner e rake vanno perfettamente bene come cron job.

Ecco una cosa molto importante che devi ricordare quando esegui lavori cron. Probabilmente non verranno chiamati dalla directory principale della tua app. Questo significa che tutti i tuoi requisiti per i file (al contrario delle librerie) dovrebbero essere fatti con il percorso esplicito: ad es. Nome file (__ FILE__) + " / other_file " ;. Questo significa anche che devi sapere come chiamarli esplicitamente da un'altra directory :-)

Controlla se il tuo codice supporta l'esecuzione da un'altra directory con

# 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

Inoltre, i lavori cron probabilmente non vengono eseguiti come te, quindi non dipendono da alcun collegamento inserito in .bashrc. Ma questo è solo un suggerimento cron standard ;-)

È interessante il fatto che nessuno abbia menzionato Sidetiq . È una bella aggiunta se stai già usando Sidekiq.

  

Sidetiq fornisce una semplice API per la definizione di lavoratori ricorrenti per   Sidekiq.

Il lavoro sarà simile al seguente:

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

  recurrence { hourly.minute_of_hour(15, 45) }

  def perform
    # do stuff ...
  end
end

Entrambi funzioneranno bene. Di solito uso script / runner.

Ecco un esempio:

0 6 * * * cd / var / www / apps / your_app / current; ./script/runner: produzione dell'ambiente "EmailSubscription.send_email_subscriptions" > > /var/www/apps/your_app/shared/log/send_email_subscriptions.log 2 > & amp; 1

Puoi anche scrivere uno script pure-Ruby per farlo se carichi i file di configurazione giusti per connetterti al tuo database.

Una cosa da tenere a mente se la memoria è preziosa è che lo script / runner (o un'attività Rake che dipende dall '"ambiente") caricherà l'intero ambiente Rails. Se hai solo bisogno di inserire alcuni record nel database, questo utilizzerà la memoria che non è necessario. Se scrivi la tua sceneggiatura, puoi evitarlo. In realtà non ho ancora avuto bisogno di farlo, ma lo sto prendendo in considerazione.

Usa Craken (processi cron rake centric)

Uso backgroundrb.

http://backgroundrb.rubyforge.org/

Lo uso per eseguire attività pianificate e attività che richiedono troppo tempo per la normale relazione client / server.

Ecco come ho impostato i miei compiti cron. Ne ho uno per fare backup giornalieri del database SQL (usando rake) e un altro per far scadere la cache una volta al mese. Qualsiasi output è registrato in un file log / cron_log. Il mio crontab è simile al seguente:

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

La prima attività cron esegue backup giornalieri del db. I contenuti di cron_tasks sono i seguenti:

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

La seconda attività è stata configurata in un secondo momento e utilizza script / runner per far scadere la cache una volta al mese (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}"

Suppongo di poter fare il backup del database in qualche altro modo, ma finora funziona per me :)

I percorsi per rastrellare e ruby ??possono variare su server diversi. Puoi vedere dove sono usando:

whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake

Usare qualcosa come Sidekiq o Resque è una soluzione molto più solida. Supportano entrambi i tentativi di lavoro, l'esclusività con un blocco REDIS, il monitoraggio e la pianificazione.

Tieni presente che Resque è un progetto morto (non attivamente mantenuto), quindi Sidekiq è un'alternativa decisamente migliore. È anche più performante: Sidekiq esegue diversi lavoratori su un singolo processo multithread mentre Resque esegue ciascun lavoratore in un processo separato.

Di recente ho creato alcuni lavori cron per i progetti a cui ho lavorato.

Ho trovato molto utile la gemma Clockwork .

require 'clockwork'

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

Puoi persino pianificare il tuo lavoro in background usando questo gioiello. Per documentazione e ulteriore assistenza, consultare https://github.com/Rykian/clockwork

Una volta ho dovuto prendere la stessa decisione e sono davvero contento di quella decisione oggi. Usa resque scheduler perché non solo un redis separato eliminerà il carico dal tuo db, ma avrai anche accesso a molti plug-in come resque-web che fornisce un'ottima interfaccia utente. Man mano che il tuo sistema si sviluppa, avrai sempre più attività da pianificare in modo da poterle controllare da un unico posto.

puoi usare la gemma resque e resque-shheduler per creare croni, questo è molto facile da fare.

https://github.com/resque/resque

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

Probabilmente il modo migliore per farlo è usare il rake per scrivere le attività che ti servono e semplicemente eseguirlo dalla riga di comando.

Puoi vedere un utile video su railscasts

Dai un'occhiata anche a queste altre risorse:

Ho usato orologio gemma e funziona abbastanza bene per me. Esiste anche la gemma clockworkd che consente di eseguire uno script come demone.

Non ne sono davvero sicuro, immagino che dipenda dal compito: quanto spesso eseguire, quanto complicato e quanta comunicazione diretta con il progetto Rails è necessario ecc. Immagino che ci fosse solo " Un modo migliore " di fare qualcosa, non ci sarebbero molti modi diversi per farlo.

Nel mio ultimo lavoro in un progetto Rails, dovevamo creare un mailer di inviti in batch (inviti al sondaggio, non spamming) che dovrebbe inviare le mail pianificate ogni volta che il server avesse tempo. Penso che avremmo usato strumenti daemon per eseguire le attività di rake che avevo creato.

Sfortunatamente, la nostra azienda ha avuto dei problemi di denaro ed è stata "acquistata" dal principale rivale, quindi il progetto non è mai stato completato, quindi non so cosa alla fine avremmo usato.

Uso lo script per eseguire cron, questo è il modo migliore per eseguire un cron. Ecco alcuni esempi di cron,

Apri CronTab - > sudo crontab -e

E incolla le linee a soffietto:

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

Ecco un formato cron, che ti aiuterà

::CRON FORMAT::

 tabella formato 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. 

Spero che questo ti possa aiutare :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top