在Rails中组织工作进程的最佳方法是什么?

Yeh*_*atz 15 queue ruby-on-rails backgroundworker

我经常有一些代码应该按计划运行或作为带有一些参数的后台进程运行.常见的元素是它们在调度过程之外运行,但需要访问Rails环境(可能还有传入的参数).

有什么好办法组织这个以及为什么?如果您想使用特定的插件或gem,请解释为什么您觉得它很方便 - 不要只列出您使用的插件.

Bob*_*man 8

我真的不喜欢像宝石delayed_job,并background_job认为坚持到数据库运行的异步作业的目的.它对我来说似乎很脏.瞬态内容不属于数据库.

即使您不需要大规模的可伸缩性,我也非常喜欢处理异步任务的消息队列.我认为,消息队列是复杂系统的理想"通用语言".对于消息队列,在大多数情况下,您对正在构建的任何内容所涉及的技术或语言没有任何限制.低并发消息队列使用的好处可能在"企业"环境中最为明显,在这种环境中,集成始终是一个巨大的痛苦.此外,当您的异步工作流涉及多个步骤时,消息队列是理想的选择.RabbitMQ是我个人的最爱.

例如,考虑您正在构建搜索引擎的场景.人们可以提交要编入索引的URI.显然,您不希望在请求中检索和索引页面.因此,您围绕消息队列构建:表单提交目标获取URI,将其抛出到要编制索引的消息队列中.下一个可用的蜘蛛进程将URI从队列中弹出,检索页面,查找所有链接,如果它们未知则将每个链接推回队列,并缓存内容.最后,将新消息推送到第二个队列,以便索引器进程处理缓存的内容.索引器进程将该消息从队列中弹出,并为缓存的内容编制索引.当然过于简单 - 搜索引擎是很多工作,但你明白了.

至于实际的守护进程,显然,我偏爱自己的库(ChainGang),但它实际上只是Kernel.fork()的一个包装器,它为您提供了一个处理设置和拆卸代码的便利位置.它还没有完成.实际上,守护进程远不如消息队列重要.

关于Rails环境,嗯,这可能最好留给读者练习,因为内存使用将成为长期运行过程的一个重要因素.您不想加载任何您不需要的东西.顺便说一下,这是DataMapper在ActiveRecord屁股上狠狠踢的一个区域.环境初始化已有详细记录,并且发现的依赖性很少,使整个工具包和cabo​​odle更加真实.

我不喜欢cron + rake的一件事是rake几乎可以保证打印到标准输出,如果你的cron作业产生输出,cron往往过于繁琐.我喜欢将所有的cron任务放在一个适当命名的目录中,然后创建一个包装它们的rake任务,这样手动运行它们是微不足道的.rake这样做很遗憾,因为我真的更愿意选择利用依赖关系.无论如何,你只需将cron直接指向脚本而不是通过cron运行它们.

我目前正在构建一个严重依赖异步进程的Web应用程序,我不得不说,我非常非常高兴我决定不使用Rails.


Luk*_*ncl 5

对我来说,不想维护大量额外的基础设施是关键优先事项,所以我使用了在Rails之外运行的数据库支持的队列.

就我而言,我使用过background_jobdelayed_job.有了background_job,工人通过cron继续运行,所以没有守护进程管理.有了delayed_job,我正在使用Heroku,让他们担心.

使用delayed_job,您可以传入与后台工作者需要运行的一样多的参数.

Delayed::Job.enqueue(MyJob.new(param[:one], param[:two], param[:three])
Run Code Online (Sandbox Code Playgroud)

除了使用script/runnervia cron(我更喜欢使用script/runnerRake任务因为我发现测试代码更容易)之外,我还没有找到一个很好的解决方案来按计划运行.

我从来没有必须有一个定期安排的后台进程,需要访问特定的Rails请求,所以这不是一个太大的问题.

我知道还有其他更酷的系统具有更多功能,但这对我来说很有用,并帮助我避免设置大量新服务来管理.