消息队列的好策略?

时间:2009-08-26 23:55:37

标签: sql-server azure message-queue

我目前正在设计一个应用程序,我最终希望迁移到Windows Azure。但是,在短期内,它将在我自己托管的服务器上运行。

该应用程序涉及许多单独的Web应用程序 - 其中一些本质上是接收数据的WCF服务,有些是用户管理数据的站点。此外,还需要在后台运行一个工作服务,它将以各种方式处理数据。

我非常希望为此使用解耦架构。理想情况下,我希望组件(即Web应用程序和工作服务)尽可能少地了解彼此。似乎使用消息队列将是最好的解决方案 - 网络应用程序可以将带有工作单元的消息排入队列,工作服务可以将它们挑选出来并根据需要进行处理。

但是,我想制定一套很好的技术来做到这一点,记住我最终会转向Azure,并希望尽量减少迁移时我需要做的工作量到云端。 Azure内置了一个Queue组件,看起来非常适合我的需求。我想做的是自己创造一些能够尽可能模仿的东西。

看起来有几个选项(我在Windows上使用.NET,带有SQL Server 2005后端) - 到目前为止我发现的是:

  • MSMQ
  • SQL Server服务代理
  • 使用数据库表和一些存储过程自行滚动

我想知道是否有人对此有任何建议 - 或者是否有人做过类似的事情,并就要做/要避免的事情提出建议。我意识到每种情况都不同,但在这种情况下,我认为我的排队要求非常通用,所以我很想听到其他人对最佳方法的看法。

提前致谢,

约翰

3 个答案:

答案 0 :(得分:18)

如果您考虑到Azure,也许您应该直接开始使用Azure,因为Azure队列与任何MSMQ或SSB之间的API和semnatics都有很大不同。

MSMQ与SSB的快速3048米比较(我会将自定义的表格排除在比较之外,因为它实际上取决于你如何实现它......)

  • 部署:MSMQ是Windows组件,SSB是SQL组件。 SSB需要SQL实例来存储任何消息,因此disconencted客户端需要访问实例(可以是Express)。 MSMQ需要在客户端上部署MSMQ(操作系统的一部分,但可选安装)。
  • 可编程性:MSMQ提供完全成熟的受支持的WCF频道。 SSB仅在http://ssbwcf.codeplex.com
  • 提供实验性WCF频道
  • 效果:在交易模式下,SSB将明显快于MSMQ。如果让我们以非交易模式运作(尽力而为,无序,交付),MSMQ将会更快。
  • Queriability :SSB队列可以是SELECTE-ed uppon(查看任何消息,完整的SQL JOIN / WHERE / ORDER / GROUP power),MSMQ队列可以偷看(只有下一条消息)
  • 可恢复性:SSB队列集成在数据库中,因此可以使用数据库对其进行备份和还原,从而使应用程序状态保持一致。 MSMQ队列在NT文件备份子系统中备份,因此为了保持备份同步(连贯),必须暂停队列数据库。
  • 交易(因为每个入队/出队都始终并伴有数据库更新):SSB完全集成在SQL中,因此出列和入队是本地事务操作。 MSMQ是一个单独的TM(事务管理器),因此queue / dequeue必须是一个分布式事务操作,以在事务中注册SQL和MSMQ。
  • 管理和监控:两者都差不多。没有任何工具。
  • 相关消息处理:SSB可以通过内置Conversation Group Locking阻止友好线程处理相关消息。
  • 事件驱动:SSB有Activation启动存储过程,MSMQ使用Windows Activation服务。类似。由于WAITFOR(RECEIVE)和MAX_QUEUE_READERS的交互方式,SSB具有自负平衡能力。
  • 可用性:SSB搭载SQL Server高可用性故事,它可以在群集或数据库镜像环境中工作。 MSMQ仅适用于Windows群集故事。数据库镜像比作为HA解决方案的群集便宜得多。

此外,我还要补充说SSB和MSMQ在它们提供的原语级别上有显着差异:SSB原语是会话,而MSMQ原语是消息。想想TCP与UDP的语义。

答案 1 :(得分:10)

选择适合您的队列后端,或者更适合您的环境的队列后端。 @Remus对MSMQ和SSB进行了很好的比较。 MSMQ将更容易实现,但有一些明显的局限性,而SSB在频谱的另一端会感觉非常沉重。

按自己的方式行事
要最小化应用程序的返工,请抽象接口后面的队列访问,然后为最终决定使用的队列传输提供实现。当它移动到Azure或其他队列传输时,您只需提供一个新的接口实现。

您可以控制您希望与队列交互的语义,从而为您的应用程序提供一致的可用API。

一个粗略的想法可能是:

interface IQueuedTransport
{
  void SendMessage(XmlDocument);
  XmlDocument ReceiveMessage();
}

public class MSMQTransport : IQueuedTransport {}
public class AzureQueueTransport : IQueuedTransport {}

您可能无法构建全面的排队运输,满足您的需求。如果您使用Xml,请传递xml。如果使用字节数组,则传递字节数组。 :)

祝你好运!
ž

答案 2 :(得分:0)

使用Win32 Mailslots。它们在单个服务器上是可靠的,易于实现,并且不需要任何额外的软件。