在Rails环境中运行定时任务,最好的方式是什么?是Script/runner还是Rake?我希望每隔几分钟运行一次任务。
在Rails环境中运行定时任务,最好的方式是什么?是Script/runner还是Rake?我希望每隔几分钟运行一次任务。
我在依赖于定时任务的项目中使用了极为流行的Whenever,它非常棒。它提供了一种漂亮的DSL来定义您的定时任务,而不是必须处理crontab格式。从README中可以看到:
Whenever是一个Ruby gem,提供了一个清晰易懂的语法,用于编写和部署cron job。
下面是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
我正在使用rake方法(heroku支持),
具体是在一个名为lib/tasks/cron.rake的文件中..
task :cron => :environment do
puts "Pulling new requests..."
EdiListener.process_new_messages
puts "done."
end
load "#{Rails.root}/lib/tasks/cron.rake"
和 rake cron
命令,但是遇到了 NameError: undefined local variable or method `cron' for main:Object 错误。 - B Seven:environment
依赖。我们有一个非常庞大的Rails应用程序,启动需要很长时间,我们的Rake每分钟都会被调用,消耗更多资源来启动Rails环境而不是执行任务。我希望能够在cron中调用已经启动的Rails环境,介于_controller_方法和_rake environment_方法之间。 - fguillen在我们的项目中,我们最初使用了 whenever gem,但遇到了一些问题。
然后我们转而使用 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
假设您的任务完成时间不太长,只需创建一个新控制器,为每个任务创建一个操作。将任务逻辑作为控制器代码实现,然后在操作的适当时间间隔设置使用wget调用此控制器和操作的URL的操作系统级别的cronjob。此方法的优点是您:
很有趣,没有人提到Sidetiq。 如果你已经在使用Sidekiq,那么这是一个不错的补充。
Sidetiq为Sidekiq定义定期工作提供了简单的API。
工作将如下所示:
class MyWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { hourly.minute_of_hour(15, 45) }
def perform
# do stuff ...
end
end
使用 script/runner
和 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技巧 ;-)
使用 Craken(基于Rake的定时任务)