ruby-on-rails - 在 Rails 中组织工作进程的最佳方式是什么?

标签 ruby-on-rails queue backgroundworker

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

什么是组织这个的好方法,为什么?如果您喜欢使用特定的插件或 gem,请说明您觉得它方便的原因——不要只列出您使用的插件。

最佳答案

我真的不喜欢像 delayed_job 这样的 gem 和 background_job为了运行异步作业而持久化到数据库中。对我来说只是看起来很脏。 transient 的东西不属于数据库。

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

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

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

关于 Rails 环境,这可能最好留给读者作为练习,因为内存使用将成为长期运行过程的一个重要因素。你不想加载任何你不需要的东西。顺便说一句,这是DataMapper 对ActiveRecord 的猛烈抨击的一个领域。环境初始化有很好的文档记录,并且发挥作用的依赖项要少得多,这使得整个套件和组合更加逼真。

我不喜欢 cron+rake 的一件事是,rake 几乎可以保证打印到标准输出,如果您的 cron 作业产生输出,则 cron 往往过于健谈。我喜欢将我所有的 cron 任务放在一个适当命名的目录中,然后制作一个包装它们的 rake 任务,这样手动运行它们就很简单了。很遗憾 rake 这样做了,因为我真的更愿意选择利用依赖项。在任何情况下,您只需将 cron 直接指向脚本,而不是通过 cron 运行它们。

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

关于ruby-on-rails - 在 Rails 中组织工作进程的最佳方式是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1101621/

相关文章:

ruby-on-rails - Rspec - 访问魔法方法/变量

ruby-on-rails - 具有多种布局的 Rails Turbolinks

javascript - 充当嵌套资源的 Votable

c# - BackgroundWorker 多线程访问表单

ruby-on-rails - rails 4 : implementation of shoryuken background process gem

c# - 变量 backgroundWorker 参数总是一样的?

ruby-on-rails - 查找在 Rails 中没有帖子的用户

python - 如何使用 celery 配置不同的工作池?

java - Java 队列中的 add 和 offer 方法有什么区别?

java - ORA-01031 : insufficient privileges creating JMS connection to Oracle topic