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


当前回答

我是资源调度程序的忠实粉丝。您不仅可以重复运行类似cron的任务,还可以在特定时间运行任务。缺点是,它需要一个Redis服务器。

其他回答

我曾经也做过同样的决定,今天我对这个决定很满意。使用resque调度程序,因为不仅一个单独的redis会从你的数据库中取出负载,你还可以访问许多插件,如resque-web,它提供了一个伟大的用户界面。随着系统的发展,你会有越来越多的任务要安排,这样你就可以从一个地方控制它们。

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

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

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

使用Sidekiq或Resque是一种更加健壮的解决方案。它们都支持重试作业、使用REDIS锁的排他性、监控和调度。

请记住,Resque是一个死项目(没有积极维护),所以Sidekiq是一个更好的选择。它的性能也更高:Sidekiq在单个多线程进程上运行多个worker,而Resque在单独的进程中运行每个worker。

在我们的项目中,我们首先使用了无论何时宝石,但遇到了一些问题。

然后我们切换到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

有意思的是没人提到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