在Rails环境中运行计划任务的最佳方法是什么?脚本/跑步吗?耙?我想每隔几分钟运行一次任务。
当前回答
有意思的是没人提到Sidetiq。 如果你已经在使用Sidekiq,这是一个很好的补充。
Sidetiq提供了一个简单的API,用于为 Sidekiq。
Job看起来是这样的:
class MyWorker
include Sidekiq::Worker
include Sidetiq::Schedulable
recurrence { hourly.minute_of_hour(15, 45) }
def perform
# do stuff ...
end
end
其他回答
假设您的任务不需要太长时间来完成,只需为每个任务创建一个带有操作的新控制器。将任务的逻辑实现为控制器代码,然后在操作系统级别上设置一个cronjob,该cronjob使用wget以适当的时间间隔调用该控制器的URL和动作。这种方法的优点是:
拥有对所有Rails对象的完全访问权,就像在普通控制器中一样。 可以像进行正常操作一样进行开发和测试。 也可以调用你的任务adhoc从一个简单的网页。 不要通过启动额外的ruby/rails进程来消耗更多的内存。
在我们的项目中,我们首先使用了无论何时宝石,但遇到了一些问题。
然后我们切换到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
下面是我如何设置我的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}"
我想我可以用其他方式备份数据库,但到目前为止,它适合我:)
rake和ruby的路径在不同的服务器上可能不同。你可以使用以下命令查看它们的位置:
whereis ruby # -> ruby: /usr/local/bin/ruby
whereis rake # -> rake: /usr/local/bin/rake
使用Sidekiq或Resque是一种更加健壮的解决方案。它们都支持重试作业、使用REDIS锁的排他性、监控和调度。
请记住,Resque是一个死项目(没有积极维护),所以Sidekiq是一个更好的选择。它的性能也更高:Sidekiq在单个多线程进程上运行多个worker,而Resque在单独的进程中运行每个worker。
最好的方法可能是使用rake来编写所需的任务,然后通过命令行执行它。
你可以在railscasts看到一个非常有用的视频
也可以看看其他资源:
Rails Rake教程
推荐文章
- 如何确定一个数组是否包含另一个数组的所有元素
- Rails find_or_create_by多个属性?
- Rails ActiveRecord日期之间
- 是什么导致这个ActiveRecord::ReadOnlyRecord错误?
- Rails:dependent =>:destroy VS:dependent =>:delete_all
- 对于PostgreSQL表来说,多大才算太大?
- Rails:如何在Rails 4中引用CSS中的图像
- 如何使用RSpec的should_raise与任何类型的异常?
- Rails -嵌套包括活动记录?
- Delete_all vs destroy_all
- Rails获取“each”循环的索引
- 如何通过脚本创建crontab
- 在rails redirect_to中传递参数
- Rails new vs create
- Rails has_many的别名