在Rails环境中运行计划任务的最佳方法是什么?脚本/运行者?耙?我想每隔几分钟运行一次任务。
在Rails环境中运行计划任务的最佳方法是什么?脚本/运行者?耙?我想每隔几分钟运行一次任务。
Answers:
我正在使用rake方法(在heroku的支持下)
带有一个名为lib / tasks / cron.rake的文件。
task :cron => :environment do
puts "Pulling new requests..."
EdiListener.process_new_messages
puts "done."
end
要从命令行执行,这只是“ rake cron”。然后可以根据需要将此命令放在操作系统cron / task调度程序上。
更新这是一个相当古老的问题和答案!一些新信息:
load "#{Rails.root}/lib/tasks/cron.rake"
和rake cron
,但是得到了NameError:main:Object的未定义局部变量或方法'cron'–
:environment
依赖性。我们有一个非常繁重的Rails应用程序,它需要很长时间才能启动,我们的Rake每分钟都会被调用一次,并消耗更多的资源来启动执行任务的Rails环境。我很想通过cron调用一个已经启动的 Rails环境,必须在控制器方法和rake环境之间进行调整。
我已经在非常依赖计划任务的项目上使用了非常受欢迎的“ 每时每刻”功能,这很棒。它为您提供了不错的DSL来定义计划的任务,而不必处理crontab格式。从自述文件:
只要有Ruby gem,它就提供了用于编写和部署cron作业的清晰语法。
自述文件中的示例:
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
在我们的项目中,我们首先使用了宝石,但是遇到了一些问题。
然后,我们切换到RUFUS SCHEDULER gem,它对于在Rails中安排任务非常简单且可靠。
我们已经使用它来发送每周和每天的邮件,甚至用于运行一些定期的rake任务或任何方法。
在此使用的代码如下:
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
要了解更多信息:https : //github.com/jmettraux/rufus-scheduler
假设您的任务完成时间不长,只需为每个任务创建一个带有动作的新控制器即可。将任务的逻辑实现为控制器代码,然后在OS级别设置一个cronjob,该任务使用wget调用该控制器的URL,并在适当的时间间隔执行操作。这种方法的优点是:
脚本/运行程序和rake任务非常适合作为cron作业运行。
这是运行cron作业时必须记住的一件事,非常重要。它们可能不会从您应用的根目录中调用。这意味着您对文件(而不是库)的所有需求都应使用显式路径来完成:例如File.dirname(__ FILE__)+“ / other_file”。这也意味着您必须知道如何从另一个目录中显式调用它们:-)
检查您的代码是否支持从另一个目录运行
# 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
另外,cron作业可能不会像您那样运行,因此,不要依赖于.bashrc中的任何快捷方式。但这只是标准的cron提示;-)
每当(和cron)出现问题时,它每次执行时都会重新加载rails环境,这在您的任务频繁或需要执行大量初始化工作时确实是一个问题。因此,我在生产中遇到了问题,必须警告您。
Rufus Scheduler为我做到了(https://github.com/jmettraux/rufus-scheduler)
当我有很长的工作要运行时,我将它与delay_job(https://github.com/collectiveidea/delayed_job)一起使用
我希望这有帮助!
我非常喜欢resque / resque调度程序。您不仅可以重复执行类似cron的任务,还可以在特定时间重复执行任务。缺点是,它需要Redis服务器。
有趣的是,没有人提到Sidetiq。如果您已经在使用Sidekiq,这是一个很好的补充。
Sidetiq提供了一个简单的API,用于为Sidekiq定义循环工作程序。
作业将如下所示:
class MyWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { hourly.minute_of_hour(15, 45) }
def perform
# do stuff ...
end
end
两者都可以正常工作。我通常使用脚本/运行器。
这是一个例子:
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
如果加载正确的配置文件以连接到数据库,您也可以编写一个纯Ruby脚本来执行此操作。
如果内存是宝贵的,要记住的一件事是脚本/运行程序(或依赖于“环境”的Rake任务)将加载整个Rails环境。如果您只需要在数据库中插入一些记录,则将使用您不需要的内存。如果您编写自己的脚本,则可以避免这种情况。我实际上并不需要这样做,但是我正在考虑。
使用Craken(以耙为中心的cron作业)
这是我设置我的cron任务的方法。我有一个每天备份SQL数据库(使用rake),另一个每月使缓存过期一次。任何输出都记录在文件log / cron_log中。我的crontab看起来像这样:
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
第一个cron任务进行每日数据库备份。cron_tasks的内容如下:
/usr/local/bin/rake db:backup RAILS_ENV=production; date; echo "END OF OUTPUT ----";
第二项任务是稍后设置的,并使用脚本/运行器每月使缓存过期一次(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}"
我想我可以用其他方式备份数据库,但到目前为止它对我有用:)
在不同的服务器上,耙和红宝石的路径可能会有所不同。您可以使用以下方法查看它们的位置:
whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake
使用Sidekiq或Resque是更可靠的解决方案。它们都支持重试作业,具有REDIS锁定的排他性,监视和计划。
请记住,Resque是一个死项目(未积极维护),因此Sidekiq是更好的选择。它还具有更高的性能:Sidekiq在单个多线程进程中运行多个工作程序,而Resque在单独的进程中运行每个工作程序。
我最近为我一直在从事的项目创建了一些cron职位。
我发现宝石发条非常有用。
require 'clockwork'
module Clockwork
every(10.seconds, 'frequent.job')
end
您甚至可以使用此gem安排您的后台作业。有关文档和更多帮助,请参阅https://github.com/Rykian/clockwork
您可以使用resque
和resque-schedular
gem来创建cron,这很容易做到。
我使用脚本运行cron,这是运行cron的最佳方法。这是cron的一些示例,
打开CronTab —> sudo crontab -e
并粘贴波纹管线:
00 00 * * * wget https://您的主机/ some_API_end_point
这是一些cron格式,对您有帮助
::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.
希望这能够帮到你 :)