2

我正在开发一个定期需要执行大量 IO 绑定操作的 Rails 应用程序。这些操作可以异步执行。例如,对于每个用户,系统每天需要查询 Salesforce.com 以获取用户当前正在跟踪的帐户(公司)列表。这会导致大量(可能 > 100k)的小查询。

我们当前的方法是将 ActiveMQ 与 ActiveMessaging 结合使用。我们的每个用户都作为不同的消息被推送到队列中。然后,消费者将用户从队列中拉出,查询 Salesforce.com 并处理结果。但是这种方法给了我们可怕的性能。在单个轮询进程中,我们一次只能处理一个用户。因此,Salesforce.com 查询变为序列化。除非我们实际上运行数百个轮询器进程,否则我们无法接近饱和运行轮询器的服务器。

我们正在寻找 EventMachine 作为替代方案。它的优势是允许我们在单个 EventMachine 进程中同时启动大量 Salesforce.com 查询。因此,我们的服务器得到了很好的并行性和利用率。

但是 EventMachine 有两个问题。1) 我们失去了使用 ActiveMQ/ActiveMessaging 提供的可靠消息传递。2) 我们不能轻易地定期重启我们的 EventMachine 来减少内存增长的影响。例如,使用 ActiveMessaging,我们有一个每天重新启动轮询器的 cron 作业,这可以在不担心丢失任何消息的情况下完成。但是使用 EventMachine,如果我们重新启动进程,我们可能会丢失数百条正在处理的消息。我能看到的唯一方法是在 EventMachine 之上构建一个持久性/可靠的交付层。

有没有人有更好的方法?可靠地执行大量异步 IO 绑定操作的最佳方法是什么?

4

4 回答 4

2

我维护 ActiveMessaging,并且一直在考虑多线程轮询器的问题,尽管可能与你们的规模不同。我会在这里给你我的想法,但也很高兴进一步讨论活动消息列表,或者如果你愿意,可以通过电子邮件。

一个技巧是轮询器不是其中唯一的序列化部分。STOMP 订阅,如果您执行 client -> ack 以防止在中断时丢失消息,则只有在先前的消息已被确认时,才会在给定连接上发送新消息。基本上,每个连接一次只能处理一条消息。

因此,要继续使用代理,诀窍是同时打开许多代理连接/订阅。当前的轮询器为此非常繁重,因为它为每个轮询器加载了整个 rails env,并且一个轮询器是一个连接。但是当前的轮询器并没有什么神奇之处,我可以想象将轮询器编写为事件机器客户端,该客户端被实现为创建与代理的新连接并一次获取许多消息。

最近在我自己的实验中,我一直在考虑使用 Ruby 企业版并拥有一个主线程来分叉许多轮询工作线程,以便获得减少内存占用的好处(就像乘客一样),但我认为 EM 技巧也可以工作。

我也是 Resque 项目的崇拜者,虽然我不知道它是否会更好地扩展到许多工人 - 我认为工人可能更轻。

http://github.com/defunkt/resque

于 2010-01-25T17:54:38.200 回答
2

我以适合您的方式将 AMQP 与 RabbitMQ 一起使用。由于 ActiveMQ 实现了 AMQP,我想您可以以类似的方式使用它。我没有使用过 ActiveMessaging,虽然它看起来是一个很棒的包,但我怀疑它可能不适合这个用例。

以下是使用 AMQP 的方法:

  • 让 Rails 进程发送一条消息说“获取用户 i 的信息”。
  • 消费者将其从消息队列中拉出,确保指定消息需要“确认”才能从队列中永久删除。这意味着如果消息没有被确认为已处理,它最终会返回到另一个工作人员的队列中。
  • 然后,工作人员将消息拆分为对 SalesForce 的数千个小请求。
  • 当所有这些请求都成功返回时,应该触发另一个回调来确认原始消息并返回一个“摘要消息”,其中包含与原始请求密切相关的所有信息。关键是使用消息队列,让您确认给定消息的成功处理,并确保仅在相关处理完成时才这样做。
  • 另一个工作人员将该消息从队列中拉出并执行任何合适的同步工作。由于所有引起延迟的位都已经执行,我想这应该没问题。

如果您使用的是 (C)Ruby,请尽量不要将同步和异步内容组合在一个进程中。一个进程应该通过 Eventmachine 完成所有事情,没有代码阻塞,或者只通过消息队列与 Eventmachine 进程对话。

此外,编写异步代码非常有用,但也难以编写、难以测试且容易出错。当心。酌情使用其他语言或工具进行调查。

于 2010-01-25T19:32:49.473 回答
1

还结帐“抽筋”和“豆茎”

于 2010-01-26T18:38:00.253 回答
0

有人给我发了以下链接:http: //github.com/mperham/evented/tree/master/qanat/。这是一个有点类似于 ActiveMessaging 的系统,只是它建立在 EventMachine 之上。这几乎正​​是我们所需要的。唯一的问题是它似乎只适用于亚马逊的队列,而不是 ActiveMQ。

于 2010-01-27T18:40:43.423 回答