¿Cuál es la mejor manera de ejecutar tareas programadas en un entorno Rails? ¿Guión / corredor? ¿Rastrillo? Me gustaría ejecutar la tarea cada pocos minutos.
¿Cuál es la mejor manera de ejecutar tareas programadas en un entorno Rails? ¿Guión / corredor? ¿Rastrillo? Me gustaría ejecutar la tarea cada pocos minutos.
Respuestas:
Estoy usando el enfoque de rastrillo (como lo admite 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 comandos, esto es solo "rake cron". Este comando se puede poner en el programador cron / task del sistema operativo como se desee.
¡Actualiza esta es una pregunta y respuesta bastante antigua! Alguna nueva información:
load "#{Rails.root}/lib/tasks/cron.rake"
y rake cron
, pero obtuve NameError: variable local indefinida o método `cron 'para main: Object
:environment
dependencia. Tenemos una aplicación Rails muy pesada que tarda mucho en iniciarse, nuestro Rake se llama cada minuto y consume más recursos al iniciar el entorno Rails que ejecutando la tarea . Me encantaría tener un entorno Rails ya iniciado para que se llame a través del cron, debe ser algo entre el enfoque del controlador y el entorno del rastrillo .
He utilizado el extremadamente popular Whenever en proyectos que dependen en gran medida de tareas programadas, y es genial. Le brinda un buen DSL para definir sus tareas programadas en lugar de tener que lidiar con el formato crontab. Desde el archivo Léame:
Siempre es una gema de Ruby que proporciona una 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, utilizamos 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 correos semanales y diarios, e incluso para ejecutar algunas tareas periódicas de rake o cualquier otro 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:
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: por ejemplo, File.dirname (__ FILE__) + "/ other_file". Esto también significa que debe saber cómo llamarlos explícitamente desde otro directorio :-)
Compruebe 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, por lo que no dependa de ningún acceso directo que ponga en .bashrc. Pero eso es solo un consejo cron estándar ;-)
El problema con when (y cron) es que vuelve a cargar 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 programador 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!
Eso es interesante, nadie mencionó el Sidetiq . Es una buena adición si ya estás usando Sidekiq.
Sidetiq proporciona una API simple para definir trabajadores recurrentes para Sidekiq.
Job 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 --environment production 'EmailSubscription.send_email_subscriptions' >> /var/www/apps/your_app/shared/log/send_email_subscriptions.log 2>&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 evitarlo. En realidad no he necesitado hacer esto todavía, pero lo estoy considerando.
Use Craken (trabajos de cron centrado en rastrillo)
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. Los contenidos de cron_tasks son los siguientes:
/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}"
Supongo que podría hacer una copia de seguridad de la base de datos de otra manera, pero hasta ahora funciona para mí :)
Los caminos al rastrillo y al rubí pueden variar en diferentes servidores. Puedes 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.
Encontré 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 con esta gema. Para obtener documentación y más ayuda, consulte https://github.com/Rykian/clockwork
puedes usar resque
y resque-schedular
gem para crear cron, esto es muy fácil de hacer.
Una vez tuve que tomar la misma decisión y estoy muy feliz con esa decisión hoy. Utilice el programador 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.
Probablemente la mejor manera de hacerlo es usar el rastrillo para escribir las tareas que necesita y simplemente ejecutarlo a través de la línea de comandos.
Puedes ver un video muy útil en railscasts
También eche un vistazo a estos otros recursos:
No estoy muy 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 hubiera "One Best Way" para 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 usar herramientas de demonio para ejecutar las tareas de rastrillo que había creado.
Desafortunadamente, nuestra compañía tuvo algunos problemas de dinero y fue "comprada" por el principal rival, por lo que el proyecto nunca se completó, por lo que no sé qué podríamos haber utilizado.
Uso script para ejecutar cron, esa es la mejor manera de ejecutar un cron. Aquí hay un ejemplo para cron,
Abra CronTab -> sudo crontab -e
Y pegar líneas de fuelle:
00 00 * * * wget https: // your_host / some_API_end_point
Aquí hay un formato cron, te ayudará
::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.
Espero que esto te ayudará :)