【问题标题】:Rails, RabbitMQ and Sidekiq Architecture [closed]Rails、RabbitMQ 和 Sidekiq 架构 [关闭]
【发布时间】:2018-08-10 16:15:41
【问题描述】:

我有一个非常琐碎的 - 我猜 - 情况,以及几个实现选择。我有一个 Rails 应用程序(称为 Core),可根据用户请求从互联网上抓取数据。爬虫没有任何业务逻辑——至少现在是这样——但是获取和持久化数据是一项需要时间的工作,我不希望它被阻塞。

我考虑过不同的架构,但是我不确定当事情扩大时哪一个会发挥最佳效果。选项:

  1. Sidekiq:每次用户请求抓取数据时,Sidekiq 中都会生成一个后台作业并抓取数据,将它们持久化并完成作业。这里可能的缺点是我不会为 Sidekiq Pro 版本付费,我不确定 OSS 版本是否适合我的需求。
  2. RabbitMQ:在Rails中开发一个微服务,我们称之为Fetcher,它将从RabbitMQ消费并获取和持久化数据。我不明白在这种情况下我是否也需要后台处理,所以再说一次 Sidekiq(或 Sneakers)。如果我这样做了,使用消息代理(在这种情况下)而不是让 Sidekiq 在同一个应用程序中进行后台处理有什么好处?

【问题讨论】:

  • 您不需要开发单独的微服务。除了您的 rails 服务器之外,您还可以将您的 rails 应用程序作为“工作人员”启动。 Sidekiq 和 Sneakers 都提供了一种方法来创建在这些“工作”进程中执行的工作/工作类。
  • Sneakers 和 Sidekiq 之间的区别在于它们存储要处理的消息的后端。 Sidekiq 使用 redis,Sneakers 使用 RabbitMQ。 Sidekiq 更精致,更易于使用 imo。您还可以将 Redis 重用于会话存储等。RabbitMQ 虽然可以让您排队更多作业并更快地处理它们,因为它可以将作业消息存储在磁盘上并且它是并发的。它也更难设置

标签: ruby-on-rails ruby rabbitmq microservices sidekiq


【解决方案1】:

您的建筑方案正朝着正确的方向发展。

  • Sidekiq OSS:我真的相信sidekiq OSS 版本将完全满足您的需求。它有几个特性来支持 Redis 支持的后台作业。我建议您阅读 its documentation 以了解最佳做法以及应避免的事项。
  • 微服务good architectural choice to achieve scalability,因为它促进功能分解,您可以就如何单独扩展每个服务做出具体决定。但是,它会以多种方式增加系统的复杂性,要​​求您高度自动化基础架构。我建议你从 Martin Fowler 网页上read this arcitle。他讨论了与采用微服务相关的权衡取舍。
  • 使用 RabbitMQ 的优点是可以在多个服务之间实现可靠的异步通信,支持可扩展性,并提供灵活的通信方式,例如 pub/sub 和 RPC。如果您保留微服务的想法,这是正确的方法。否则,一个单一的 Rails 应用程序将只需要使用 sidekiq。
  • 如果你使用 RabbitMQ,你应该使用正确的RabbitMQ client。对于 ruby​​,在发布者和消费者服务中都使用 Bunny,因为它将为 publish data on RabbitMQsupport background processing for receiving data 提供良好的 API。因此,Fetcher 服务中无需使用 sidekiq 来消费数据。
  • 当您要进行异步处理时,您的客户端将不知道他们的请求与您的 HTTP 响应的最终结果。因此,使用一种机制让您的应用程序在您的应用程序完成异步处理任务时通知他们(即通过用户页面上的状态更新)会很有趣。为此,您可以使用 Websockets,Rails 已通过 Action Cable 支持该功能。

我的最后一个提示是:如果您仍在为您的应用程序设计原型并尝试各种想法,我建议您遵循单体架构的道路,并更关注验证您的提案。但是,如果您已经有一个结构良好的提案并且知道应用程序的预期需求,那么微服务架构可能是开发可扩展且可靠的系统的不错选择。

【讨论】:

  • 非常感谢非常详细的回复和亚瑟的所有指点。这里有一个小的跟进:Bunny 确实支持 RabbitMQ 的消费者,但我还没有找到可以像 Sidekiq 那样扇出多个线程的示例。我的意思是,如果我采用 Bunny 方式,我是否必须自己实现后台处理?我见过的几乎所有例子都使用 bunny 和 Sneakers 工人。假设 Fetcher rails 应用程序使用来自 RabbitMQ 的数据,因此它会收到一条消息并开始处理。据我了解,在完成第一条消息之前,它无法收到另一条消息,我是否遗漏了什么?
  • 看看这个link。它探讨了 Bunny 的一些并发方面。更准确地说,Consumer Work Pools 部分定义了如何设置线程池大小。因此,Bunny 将为消费者创建线程,默认情况下可能不会阻塞您的主线程(参见 block 参数)。 IMO,这就是不使用sidekiq的原因。更多细节请看subscribe method of Bunny's Queue class的实现。
  • 此外,如果您可以have competing consumers 来扩展队列的读取。例如,Puma 将为您的应用程序启动并发进程和线程,从而为您的应用程序添加竞争消费者。
猜你喜欢
  • 2018-08-26
  • 1970-01-01
  • 2012-06-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-21
  • 1970-01-01
  • 2011-12-22
  • 2012-07-19
相关资源
最近更新 更多