Pregunta

¿Cuál es la mejor manera de ejecutar tareas programadas en un entorno Rails? ¿Guión / corredor? Rastrillo?

¿Fue útil?

Solución

Estoy usando el enfoque de ataque (según lo respaldado por heroku )

Con un archivo llamado lib / task / cron.rake ..

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

Para ejecutar desde la línea de comando, esto es simplemente "rake cron". Este comando se puede colocar en el programador cron / task del sistema operativo como se desee.

Actualización ¡esta es una pregunta y respuesta bastante antigua! Alguna información nueva:

  • el servicio cron de heroku al que hice referencia ha sido reemplazado por Heroku Scheduler
  • para tareas frecuentes (especialmente donde desea evitar el costo de inicio del entorno Rails) mi enfoque preferido es usar el cron del sistema para llamar a un script que (a) empujará una API webhook segura / privada para invocar la tarea requerida en segundo plano o (b) coloque directamente una tarea en el sistema de colas que elija

Otros consejos

He usado el extremadamente popular Whenever en proyectos que dependen en gran medida de tareas programadas, y es genial . Le da un buen DSL para definir sus tareas programadas en lugar de tener que lidiar con el formato crontab. Desde el archivo README:

  

Siempre que sea una gema de rubí que proporcione un   sintaxis clara para escribir y desplegar   trabajos cron.

Ejemplo de 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

En nuestro proyecto usamos por primera vez gema, pero enfrentamos algunos problemas.

Luego cambiamos a RUFUS SCHEDULER gema, que resultó ser muy fácil y confiable para programar tareas en Rails.

Lo hemos usado para enviar semanalmente & amp; correos diarios, e incluso para ejecutar algunas tareas periódicas de rake o cualquier método.

El código utilizado en esto es como:

    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

Para obtener más información: https://github.com/jmettraux/rufus-scheduler

Suponiendo que sus tareas no tarden demasiado en completarse, simplemente cree un nuevo controlador con una acción para cada tarea. Implemente la lógica de la tarea como código del controlador, luego configure un cronjob en el nivel del sistema operativo que use wget para invocar la URL de este controlador y la acción en los intervalos de tiempo apropiados. Las ventajas de este método son usted:

  1. Tenga acceso completo a todos sus objetos Rails como en un controlador normal.
  2. Puede desarrollarse y probarse tal como lo hace con las acciones normales.
  3. También puede invocar sus tareas ad hoc desde una página web simple.
  4. No consuma más memoria activando procesos adicionales de ruby ??/ rails.

El problema con when (y cron) es que recarga el entorno de rails cada vez que se ejecuta, lo cual es un problema real cuando sus tareas son frecuentes o tienen mucho trabajo de inicialización. He tenido problemas en la producción debido a esto y debo advertirte.

El planificador de Rufus lo hace por mí ( https://github.com/jmettraux/rufus-scheduler )

Cuando tengo trabajos largos para ejecutar, lo uso con delayed_job ( https://github.com/collectiveidea/delayed_job )

¡Espero que esto ayude!

Soy un gran admirador de resque / planificador de resque . No solo puede ejecutar tareas repetitivas de tipo cron, sino también tareas en momentos específicos. La desventaja es que requiere un servidor Redis.

las tareas de script / runner y rake están perfectamente bien para ejecutarse como trabajos cron.

Aquí hay una cosa muy importante que debe recordar al ejecutar trabajos cron. Probablemente no se llamarán desde el directorio raíz de su aplicación. Esto significa que todas sus necesidades de archivos (a diferencia de las bibliotecas) deben hacerse con la ruta explícita: p. File.dirname (__ FILE__) + " / other_file " ;. Esto también significa que debe saber cómo llamarlos explícitamente desde otro directorio :-)

Verifique si su código admite la ejecución desde otro directorio 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

Además, los trabajos cron probablemente no se ejecuten como usted, así que no dependa de ningún acceso directo que haya puesto en .bashrc. Pero eso es solo un consejo cron estándar ;-)

Eso es interesante, nadie mencionó el Sidetiq . Es una buena adición si ya está usando Sidekiq.

  

Sidetiq proporciona una API simple para definir trabajadores recurrentes para   Sidekiq.

El trabajo se verá así:

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

  recurrence { hourly.minute_of_hour(15, 45) }

  def perform
    # do stuff ...
  end
end

Ambos funcionarán bien. Usualmente uso script / runner.

Aquí hay un ejemplo:

0 6 * * * cd / var / www / apps / your_app / current; ./script/runner - producción ambiental 'EmailSubscription.send_email_subscriptions' > > /var/www/apps/your_app/shared/log/send_email_subscriptions.log 2 > & amp; 1

También puede escribir un script de Ruby puro para hacer esto si carga los archivos de configuración correctos para conectarse a su base de datos.

Una cosa a tener en cuenta si la memoria es preciosa es que el script / runner (o una tarea Rake que depende del 'entorno') cargará todo el entorno Rails. Si solo necesita insertar algunos registros en la base de datos, esto usará memoria que realmente no tiene que usar. Si escribe su propio guión, puede evitar esto. En realidad no he necesitado hacer esto todavía, pero lo estoy considerando.

Use Craken (rake centrado en trabajos cron)

Yo uso backgroundrb.

http://backgroundrb.rubyforge.org/

Lo uso para ejecutar tareas programadas, así como tareas que toman demasiado tiempo para la relación normal cliente / servidor.

Así es como configuré mis tareas cron. Tengo uno para hacer copias de seguridad diarias de la base de datos SQL (usando rake) y otro para caducar el caché una vez al mes. Cualquier salida se registra en un archivo log / cron_log. Mi crontab se ve así:

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 primera tarea cron realiza copias de seguridad diarias de db. El contenido de cron_tasks es el siguiente:

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

La segunda tarea se configuró más tarde y usa script / runner para expirar el caché una vez al mes (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}"

Creo que podría hacer una copia de seguridad de la base de datos de otra manera, pero hasta ahora funciona para mí :)

Las rutas para rastrillar y rubí pueden variar en diferentes servidores. Puede ver dónde están usando:

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

Usar algo Sidekiq o Resque es una solución mucho más robusta. Ambos admiten el reintento de trabajos, la exclusividad con un bloqueo REDIS, el monitoreo y la programación.

Tenga en cuenta que Resque es un proyecto muerto (no mantenido activamente), por lo que Sidekiq es una alternativa mucho mejor. También es más eficiente: Sidekiq ejecuta a varios trabajadores en un solo proceso multiproceso, mientras que Resque ejecuta a cada trabajador en un proceso separado.

Recientemente he creado algunos trabajos cron para los proyectos en los que he estado trabajando.

Descubrí que la gema Clockwork es muy útil.

require 'clockwork'

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

Incluso puedes programar tu trabajo en segundo plano usando esta gema. Para obtener documentación y ayuda adicional, consulte https://github.com/Rykian/clockwork

Una vez tuve que tomar la misma decisión y estoy muy feliz con esa decisión hoy. Utilice el planificador de resque porque no solo un redis separado eliminará la carga de su base de datos, sino que también tendrá acceso a muchos complementos como resque-web que proporciona una excelente interfaz de usuario. A medida que su sistema se desarrolle, tendrá que programar más y más tareas para poder controlarlas desde un solo lugar.

puedes usar resque y resque-shheduler gem para crear crons, esto es muy fácil de hacer.

https://github.com/resque/resque

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

Probablemente la mejor manera de hacerlo es usando rake para escribir las tareas que necesita y simplemente ejecutarlo a través de la línea de comandos.

Puede ver un muy útil video en railscasts

También eche un vistazo a estos otros recursos:

Utilicé clockwork gem y funciona bastante bien para mí. También hay una gema clockworkd que permite que un script se ejecute como demonio.

No estoy realmente seguro, supongo que depende de la tarea: con qué frecuencia se ejecuta, qué tan complicado y cuánta comunicación directa se necesita con el proyecto de rieles, etc. Supongo que si solo hubiera " Una mejor manera " de hacer algo, no habría tantas formas diferentes de hacerlo.

En mi último trabajo en un proyecto de Rails, necesitábamos hacer un envío por correo de invitación por lotes (invitaciones a encuestas, no spam) que debería enviar los correos planificados siempre que el servidor tuviera tiempo. Creo que íbamos a utilizar herramientas de demonio para ejecutar las tareas de rake que había creado.

Desafortunadamente, nuestra empresa tuvo algunos problemas de dinero y fue "comprada" por el rival principal, por lo que el proyecto nunca se completó, por lo que no sé qué habríamos utilizado eventualmente.

Uso script para ejecutar cron, esa es la mejor manera de ejecutar un cron. Aquí hay un ejemplo para cron,

Abra CronTab & # 8212; > sudo crontab -e

Y pegar líneas de fuelle:

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

Aquí hay un formato cron, lo ayudará

::CRON FORMAT::

 tabla de 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. 

Espero que esto te ayude :)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top