在Rails环境中运行计划任务的最佳方法是什么?脚本/跑步吗?耙?我想每隔几分钟运行一次任务。


当前回答

我正在使用耙方法(由heroku支持)

使用名为lib/tasks/cron的文件。rake . .

task :cron => :environment do
  puts "Pulling new requests..."
  EdiListener.process_new_messages
  puts "done."
end

要从命令行执行,这就是“rake cron”。然后可以根据需要将此命令放到操作系统cron/任务调度程序上。

更新这是一个相当老的问题和答案!一些新信息:

我引用的heroku cron服务已经被heroku Scheduler所取代 对于频繁的任务(特别是当你想避免Rails环境启动成本时),我的首选方法是使用系统cron来调用一个脚本,该脚本将(a)戳一个安全/私有webhook API来在后台调用所需的任务,或者(b)直接在你选择的排队系统上排队任务

其他回答

假设您的任务不需要太长时间来完成,只需为每个任务创建一个带有操作的新控制器。将任务的逻辑实现为控制器代码,然后在操作系统级别上设置一个cronjob,该cronjob使用wget以适当的时间间隔调用该控制器的URL和动作。这种方法的优点是:

拥有对所有Rails对象的完全访问权,就像在普通控制器中一样。 可以像进行正常操作一样进行开发和测试。 也可以调用你的任务adhoc从一个简单的网页。 不要通过启动额外的ruby/rails进程来消耗更多的内存。

我使用backgrounddrb。

http://backgroundrb.rubyforge.org/

我用它来运行预定的任务以及对于正常的客户机/服务器关系花费太长时间的任务。

下面是我如何设置我的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。

我不太确定,我猜这取决于任务:多长时间运行一次,有多复杂,需要与rails项目进行多少直接交流等等。我想如果做一件事只有“一种最好的方法”,就不会有那么多不同的方法了。

在我在Rails项目中的上一份工作中,我们需要制作一个批量邀请邮件(调查邀请,而不是垃圾邮件),它应该在服务器有时间的时候发送计划好的邮件。我认为我们将使用守护进程工具来运行我创建的rake任务。

不幸的是,我们公司遇到了一些资金问题,被主要竞争对手“收购”了,所以这个项目一直没有完成,所以我不知道我们最终会用什么。