Un trabajo cron para rails: ¿mejores prácticas?
¿Cuál es la mejor manera de ejecutar tareas programadas en un entorno Rails? Guión / corredor? ¿Rastrillo?
20 answers
Estoy usando el enfoque de rake (según lo soportado por heroku )
Con un archivo llamado lib/tasks/cron.rastrillo ..
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 "rastrillo cron". Este comando se puede poner en el sistema operativo cron/programador de tareas como se desee.
Update ¡esta es una vieja pregunta y respuesta! Nueva información:
- el servicio heroku cron al que me referí ha sido reemplazado por Heroku Planificador
- para tareas frecuentes (esp. donde desea evitar el costo de inicio del entorno Rails) mi enfoque preferido es usar system cron para llamar a un script que (a) pinchará una API de webhook segura/privada para invocar la tarea requerida en segundo plano o (b) encolará directamente una tarea en su sistema de colas de elección
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-11 09:40:54
He usado el extremadamente popular Siempre que 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. Del README:
Whenever es una gema Ruby que proporciona una sintaxis clara para escribir e implementar cron jobs.
Ejemplo del 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-16 20:01:28
Asumiendo que sus tareas no tardan 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 de 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:
- Tenga acceso completo a todos sus objetos Rails como en un controlador normal.
- Puede desarrollarse y probarse tal como lo hace normalmente acto.
- También puede invocar sus tareas adhoc desde una página web simple.
- No consuma más memoria activando procesos ruby/rails adicionales.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-30 19:59:35
En nuestro proyecto usamos por primera vez gem, pero nos enfrentamos a algunos problemas.
Luego cambiamos a RUFUS SCHEDULER gem, que resultó ser muy fácil y fiable para programar tareas en Rails.
Lo hemos utilizado para enviar correos semanales y diarios, e incluso para ejecutar algunas tareas periódicas de rake o cualquier método.
El código usado 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 saber más: https://github.com/jmettraux/rufus-scheduler
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-30 07:29:20
El problema con whenever (y cron) es que recarga el entorno rails cada vez que se ejecuta, lo cual es un problema real cuando tus tareas son frecuentes o tienen mucho trabajo de inicialización que hacer. He tenido problemas en la producción debido a esto y debo advertirle.
Rufus scheduler lo hace por mí ( https://github.com/jmettraux/rufus-scheduler )
Cuando tengo trabajos largos que ejecutar, los uso con delayed_job ( https://github.com/collectiveidea/delayed_job )
Espero que esto ayude!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-21 22:04:17
Soy un gran fan de resque/resque programador. No solo puede ejecutar tareas repetitivas similares a cron, sino también tareas en momentos específicos. La desventaja es que requiere un servidor Redis.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-11 04:43:25
Las tareas 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 tu aplicación. Esto significa que todos los requisitos para los archivos (a diferencia de las bibliotecas) deben hacerse con la ruta explícita: por ejemplo, Archivo.dirname(__FILE__) + "/ other_file". Esto también significa que debe saber cómo llamarlos explícitamente desde otro directorio: -)
Compruebe si su código soporta 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 tú, así que no dependas de ningún atajo que pongas .bashrc. Pero eso es solo una punta cron estándar; -)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-13 14:43:53
Ambos funcionarán bien. Normalmente 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 pure-Ruby 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 script/runner (o una tarea de Rake que depende de 'environment') cargará todo el entorno Rails. Si solo necesita insertar algunos registros en la base de datos, esto usará memoria que realmente no tiene a. Si escribes tu propio guión, puedes evitar esto. En realidad no he necesitado hacer esto todavía, pero lo estoy considerando.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-14 18:19:17
Use Craken (rake centric cron jobs)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-28 21:11:22
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.
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-14 22:05:57
Uso backgroundrb.
Http://backgroundrb.rubyforge.org /
Lo uso para ejecutar tareas programadas, así como tareas que toman demasiado tiempo para la relación cliente/servidor normal.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-11-13 00:12:04
Así es como he configurado mis tareas cron. Tengo uno para hacer copias de seguridad diarias de la base de datos SQL (usando rake) y otro para caducar la 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 la base de datos. 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 la 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 respaldar base de datos de alguna otra manera, pero hasta ahora funciona para mí:)
Las rutas a rake y ruby 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 trabajos de reintegro, exclusividad con un bloqueo de REDIS, monitoreo y 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 varios trabajadores en un solo proceso de varios hilos, mientras que Resque ejecuta cada trabajador en un proceso separado.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-16 18:23:08
Recientemente he creado algunos trabajos cron para los proyectos en los que he estado trabajando.
Encontré que la gema Mecanismo muy útil.
require 'clockwork'
module Clockwork
every(10.seconds, 'frequent.job')
end
Incluso puede programar su trabajo en segundo plano usando esta gema. Para obtener documentación y más ayuda, consulte https://github.com/Rykian/clockwork
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-07 14:42:23
Una vez tuve que tomar la misma decisión y estoy muy contento con esa decisión hoy. Use resque scheduler porque no solo un redis separado eliminará la carga de su base de datos, también tendrá acceso a muchos complementos como resque-web, que proporciona una gran interfaz de usuario. A medida que tu sistema se desarrolle tendrás más y más tareas que programar por lo que podrás controlarlas desde un solo lugar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-01 20:07:14
Puede usar resque y resque-shheduler gem para crear crons, esto es muy fácil de hacer.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-26 18:10:29
Probablemente la mejor manera de hacerlo es usar rake 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:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-14 20:17:35
Usé clockwork gem y funciona bastante bien para mí. También hay una gema clockworkd
que permite que un script se ejecute como un demonio.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-03 02:33:28
No estoy muy seguro, supongo que depende de la tarea: la frecuencia de ejecución, la complejidad y la comunicación directa con el proyecto rails, etc. Supongo que si solo hubiera "Una Mejor Manera" de hacer algo, no habría tantas maneras diferentes de hacerlo.
En mi último trabajo en un proyecto Rails, necesitábamos hacer un correo de invitación por lotes (invitaciones a encuestas, no spamming) que debería enviar los correos planificados cada vez que el servidor tuviera tiempo. Creo que estábamos voy a usar daemon tools para ejecutar las tareas de rake 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 se qué habríamos usado eventualmente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-22 14:52:12
Utilizo script para ejecutar cron, esa es la mejor manera de ejecutar un cron. Aquí hay un ejemplo para cron,
Abrir CronTab - > sudo crontab-e
Y Pegue Las líneas De Abajo:
00 00 * * * wget https://your_host/some_API_end_point
Aquí hay algunos cron formato, le 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 ayude:)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-21 10:27:45