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

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

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

我真的不喜欢像delayed_jobbackground_job这样的gem,它们为了运行异步作业而持久存储到数据库中。 它对我来说似乎很脏。 瞬态内容不属于数据库。

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

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

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

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

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

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

我有一个接收请求的系统,然后需要使用Web服务调用多个外部系统。 其中一些请求需要的时间比用户预期的要长,我使用企业排队系统(activemq)来处理这些请求。

我正在使用ActiveMessaging插件来执行此操作。 这允许我编组请求并将其放在队列上以进行异步处理以访问请求数据,但是如果要等待响应,则需要编写轮询服务。

我看过Ryan Bates在Starling和 Workling上的video直播 ,他们看起来很有希望,但我还没有使用它们。

对于定期安排的任务,我只使用rake任务。 它简单,易于测试,易于理解,并与Rails环境很好地集成。 然后用你需要的任何时间间隔用cron作业执行这些rake任务(我用它来管理这些工作,因为我有点cron-illiterate)。