JRuby on Rails的调度选项

13
我正在使用JRuby 1.5.6 on Rails构建一个应用程序,该应用程序将定期离开并检索我订阅的任何RSS播客。我选择JRuby主要是因为我熟悉Java,希望利用Rails框架,并且最重要的是当Ruby无法满足我的需求时,我能够在Java中执行“重活”。到目前为止(我仍处于开发的早期阶段),这种混合方法非常有效。现在,我需要实现对后台进程的定期和长时间运行任务的调度。我的要求是具有数据库支持的调度系统,最好是有良好文档记录、当前维护和干净的系统。我的问题是,经过多天的研究适合的gem包解决方案,由于我使用JRuby,我似乎只剩下很少的选择。我尝试了一些gem,例如rufus scheduler和delayed_job等,但它们都存在一些问题,比如缺乏数据库持久性或依赖于不能在JRuby上正常工作的gem。

这个github上的分支不依赖于守护进程(daemons),但是我不想切换到主开发分支之外的分支,而且我仍然面临ObjectSpace问题,我不确定它对性能的影响。

quartz-jruby

虽然之前已经有了各种基于quartz的gems,但这个非常新的提供另一种提供类似Ruby风格接口的尝试。然而文档很少,我不确定它是否可以支持数据库,我的直觉是不行。

问题

虽然我在这里只强调了3个选项,但我知道还有其他可用的选项。然而,我一直没有找到一个解决方案来满足所有三个要求(文档、维护、支持数据库)。

所以问题是...

还有其他人遇到过这种情况并找到了解决方案吗?

有人成功地使用延迟作业(delayed_job)吗?

是否有更好的解决方案被忽视了,可以满足我的需求?


1
更新:我认为值得发布我使用JRuby的最终解决方案,现在版本为1.7.2。我当前的设置使用Sidekiq和Clockwork。它已被证明是一种可靠的长期解决方案。 - Phil Ostler
4个回答

4

我们已经在生产环境中使用了一年以上的delayed_job(collectiveidea/v1.8.4),并且在JRuby下运行。我们没有启用ObjectSpace,也没有使用daemons gem。

创建了一个简单的rake任务

  namespace :product do
    desc "Start Delayed Job Worker"
    task :dw => :environment do
      Delayed::Worker.new.start
    end
  end

并以操作系统相关的方式将其守护化。 在Linux上,

nohup jruby -S rake product:dw > $log_dir/delayed_job_console.log  2>&1 &

1
我认为这与运行<rake jobs:work>类似,正如您在[..]/gems/delayed_job-3.0.3/lib/delayed/tasks.rb中所看到的-->任务:工作=>:环境延迟::Worker.new(:min_priority => ENV['MIN_PRIORITY'], :max_priority => ENV['MAX_PRIORITY'], :queues => (ENV['QUEUES'] || ENV['QUEUE'] || '').split(','), :quiet => false).start - Fernando Fabreti

4
我建议使用Resque作为队列系统。Resque类似于DelayedJob,但在我看来更好。它是GitHub开发的,并被用作他们的队列系统。我也已经在生产中使用它将近一年了,感到非常满意。
Resque肯定支持JRuby,而且你只需要有一个简单的调度程序就可以获得预定的工作。有些人推荐resque-scheduler,但我喜欢保持简单,使用clockwork,它有一个很好的DSL,可以编写类似于cron的简单任务以排队调度程序(请参见:clockwork README)。这样,你就可以像这样安排事情:
every(1.hour, 'tasks.alert') { Resque.push(:cron, :class => 'TaskAlert', :args => []) }

2

请查看https://github.com/kares/jruby-rack-worker 这个工具可以在jruby环境下实现延迟任务。 目前仍在开发中。 在撰写本文时,我的经验是它可以正常运行单个工作进程。 但我在启动额外的工作进程时遇到了困难。


一开始运行得很好,但现在每次都被锁住了。你有什么想法吗? - Sully

1

我最初在2010年12月提出了这个问题,后来开发了一个解决方案,我认为值得回帖供其他人参考。

正如其他人指出的那样,使用JRuby等库是可能的,对于某些人来说,这可能是可接受的解决方案。然而,我不想要需要运行额外进程的解决方案,并且基于此,我开发了一个宝石(gem) ,利用了Java的Executor框架并将其与ActiveRecord集成。

结果就是acts_as_executor,它允许Rails 3.x应用程序与执行器和任务(这将在真正的Java线程中运行)交互,就像处理任何其他 ActiveRecord 模型一样。

我最近已经将该宝石升级到发布候选版本1。请查看GitHubRubygems

N.B. RubyGems默认页面出现了beta2,原因不详。但rc1仍然是最新版本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接