5

在 AppHarbor 研究构建一个在 MVC4 上运行的 Web 应用程序。出于响应和性能的考虑,运行时间稍长的任务(通常是生成/发送电子邮件、调整图像大小、支付交易处理等)将通过将消息放在消息队列中来处理。

也会有一个或多个工作人员,在某个地方,将消息出列并处理任何需要处理的结果。中央队列机制是 RabbitMQ,特别是通过 AppHarbor 提供的托管 CloudAMQP 服务。从理论上讲,这种架构可以通过添加更多工作人员来实现“无限”可扩展性。

现在,为了良好的架构、可测试性等,我想将 RabbitMQ 放在一个或多个易于模拟的接口后面。在定义这些接口时,我需要考虑一些因素。

  • 在我获得任何付费用户之前,我仅限于免费的 CloudAMQP 产品。这意味着最多三个同时连接。
  • 鉴于前面的限制,我想尝试将自己限制为每个应用程序一个连接。一个用于 MVC 应用程序,每个工作人员一个。而已。
  • RabbitMQ 中的连接被设计为长期存在。尽管如此,许多示例显示了显式打开连接(然后是通道),发送消息,然后再次关闭它的代码。
  • 对于多线程,可以使用相同的连接,但不能使用相同的通道。据我了解,可以在多线程应用程序中共享连接,然后打开多个通道,例如每个线程一个。
  • 我的 MVC 应用程序通常只是一个发布者。工作者应用程序既是消费者又是发布者——例如,工作者可以接收处理付款的消息,这将导致它发布消息以调用电子邮件消息给用户,指示成功或失败。
  • 对于 MVC 应用程序,连接通常只使用很短的时间 - 用于排队消息。
  • 对于工人,我正在考虑长期运行的连接,或多或少地在工人的一生中永久开放。

好的,太好了,这就是很多东西。在这个项目之前没有任何使用 RabbitMQ 的经验,我被一些额外的要点困扰着。

  • 接口隔离原则。我应该把它分成两个独立的接口——比如 IQueueServiceConsumer 和 IQueueServiceProducer——还是太过分了?我发现我总是可以使用 SRP 等将事物进一步划分为更多的原子单元,而且我不希望 Bob 叔叔追捕我(比接口名称中的 I 更多),但我想知道我必须走多远拿着这个。
  • 鉴于我将只有一个网络服务器,至少一开始是这样,在网络应用程序中实际上与队列建立长期连接是否是一个想法?打开和关闭它们提供了同时发生多个的理论上的机会,这意味着冲突和潜在的信息丢失。消息丢失是不可接受的。
  • 在这种情况下,我将如何处理连接的生命周期?在我的 Ninject 模块中打开它(我的接口实际上绑定到特定于 RabbitMQ 的实现),并在应用程序被回收时以某种方式断开它...回收?我怎么能做那样的事情?
  • 对于工人来说,生活似乎更轻松了。在接口上放置一个方法来打开连接,然后为线程提供通道以获取消息。通过适当地调用 CloseConnection 来确保应用程序运行良好。或者实现 IDisposable。
  • 有一个机会——无论多么小——RabbitMQ 将来可能会被其他东西取代,因此我不希望我的接口过于特定于那个特定的服务总线(从某种意义上说,这就是我使用它的方式)执行。

在构建类似的应用程序时,其他人是否已经经历过同样的挑战?您对消息队列接口的架构和实际实现有什么建议吗?我只是对此感到神经质还是我的担忧值得承认?

如果重要的话,我当前的消息传递需求由单向消息覆盖,除了在处理完成后确认收到的消息之外不需要任何响应。

感谢您的任何见解!

4

2 回答 2

1

您也可以使用NServiceBus但需要挂钩 RabbitMq 传输。传输当前未更新到 NSB 3.2,但这将是一个很好的练习,也是您身边的社区支持。

于 2012-05-28T10:09:04.200 回答
1

Masstransit将为您完成所有这些工作。要么使用 MT,要么看看他们做了什么

于 2012-05-27T20:06:27.723 回答