我应该使用 MSMQ 还是 SQL Service Broker 进行事务处理?
Posted
技术标签:
【中文标题】我应该使用 MSMQ 还是 SQL Service Broker 进行事务处理?【英文标题】:Should I use MSMQ or SQL Service Broker for transactions? 【发布时间】:2010-09-19 10:06:50 【问题描述】:我的团队负责人要求我调查 MSMQ 作为我们新版本产品的一个选项。我们在当前版本中使用 SQL Service Broker。我已经完成了相当多的实验和谷歌搜索,以找到哪种产品更适合我的需求,但我想我会询问我所知道的最好的网站来获得编程答案。
一些细节:
我们的客户端是.NET 1.1和2.0代码;这是发送消息的地方。 SQL Server 2005 实例中的目标。所有消息最终都是数据库更新或插入。 我们将发送一些必须作为交易处理的更新。 我们必须有完美的消息可恢复性;没有消息可以丢失。 我们必须是异步的,并且即使在目标 SQL 服务器关闭时也能够接受消息。 开发我们自己的排队解决方案不是一种选择;我们是一个小团队。到目前为止我发现的东西:
MSMQ 和 SQL Service Broker 都可以完成这项工作。 似乎服务代理处理事务性消息的速度更快。 Service Broker 需要在某处运行 SQL 服务器,而 MSMQ 需要在某处运行任何已配置的 Windows 计算机。 MSMQ 似乎更好/更快/更容易在集群中设置/运行。我错过了什么吗?这里有明显的赢家吗?任何想法、经验或链接都会受到重视。谢谢!
编辑:我们最终坚持使用服务代理,因为我们在一些客户端代码中使用了自定义数据库框架(我们更好地处理事务)。该代码捕获了事务的 SQL,但没有捕获 .客户端代码也是 .NET 的所有 1.1 版本,因此我们必须升级所有客户端代码。感谢您的帮助!
【问题讨论】:
如果您的客户端代码在数据库服务器以外的机器上运行,请确保测试回滚方案。我遇到了一些问题,当我处理队列并且由于远程端点关闭而需要失败时,我最终会在服务代理中删除队列,因为它在离线之前只能处理 5 次失败。为了解决这个问题,我必须禁用 Service Broker 的事务并依赖代码中的异常处理,这意味着在某些故障下我会完全丢失消息。 最后的选择是什么?如果现在问还为时不晚:)。 @the coon:我们最终使用了 SQL Service Broker,它运行良好(正如我在上面的编辑中提到的)。这在当时对我们来说是更好的选择,尽管我认为(在这两者之间)如果我要从头开始重建系统,我会使用 MSMQ。 【参考方案1】:刚刚将我的应用程序从 Service Broker 迁移到 MSMQ,我必须投票支持使用 MSMQ。有几个因素需要考虑,但其中大部分与您使用数据的方式以及处理的位置有关。
是否在数据库中进行处理? 服务代理 如果只是数据移动? 服务代理 是否在 .NET/COM 代码中进行处理? MSMQ 您是否需要远程分布式事务(例如,在不同于 SQL 的机器上处理)? MSMQ 您是否需要能够在目标关闭时发送消息? MSMQ 您想使用 nServiceBus、MassTransit、Rhino-ESB 等吗? MSMQ无论您选择什么都需要考虑的事情
您如何知道队列的健康状况?这两个选项处理故障转移的方式不同。例如,Service Broker 会在某些情况下禁用您的队列,这可能会导致您的应用程序瘫痪。 您将如何执行报告?如果您已经在报告中使用 SQL 表,Service Broker 可以轻松融入,因为它只是另一个动态表。如果您已经在使用性能监视器 MSMQ 可能会更好。 Service Broker 确实有很多性能计数器,所以不要让这成为您的唯一因素。 如何衡量正常运行时间?仅仅是确保您不会丢失交易,还是需要同步响应?我发现 MSMQ 的分布式特性允许更长的正常运行时间,因为主队列可以离线并且不会丢失任何东西。而对于 Service Broker,您的数据库必须在线,否则您将失败。 您是否已经使用过这些技术之一?两者都有很多实现细节,可能会反过来咬你。 无论您做出何种选择,切换底层队列技术有多容易?我建议您使用一个通用的 IQueue 接口来编写具体的实现。这样,如果您发现自己做出了错误的选择,以后可以轻松地更改您所做的选择。毕竟,队列只是一个队列,不应将您锁定在特定的实现中。【讨论】:
“您是否需要能够在目标关闭时发送消息?MSMQ” - 您可以使用 Service Broker 执行此操作,您只需要有一个本地数据库来保存发送队列。 我知道这个答案是 4 年前的……但是您始终能够使用 Service Broker 远程和过渡地处理队列。 (只要您不使用路由,您就可以使用 SQL express 免费进行。)是的,Microsoft 的 .Net 客户端包装器有点糟糕,但使用 ADO.Net 或 Entity Framework 包装 SQL 命令真的很容易.通过在主循环顶部放置“启用队列”语句可以轻松解决 5 次回滚后关闭的队列。【参考方案2】:我以前使用过 MSMQ,我要添加到您的列表中的唯一项目是版本控制的先决条件检查。我遇到了一个问题,其中一个站点具有 Win 2000 Server 和 MSMQ v.2,而不是 Win 2003 Server 和 MSMQ v3。我所有的 .NET 代码都以 v.3 为目标,它们不兼容......或者至少不容易兼容。
如果您走 MSMQ 路线,请考虑一下。
【讨论】:
【参考方案3】:MSMQ 中的消息大小限制阻止了我朝那个方向的挖掘。我正在为该项目学习 Service Broker。
【讨论】:
【参考方案4】:您是否需要能够在目的地关闭时发送消息? MSMQ
我不明白为什么? SSB 可以毫无问题地将消息发送到断开连接的目的地。所有这些消息都进入传输队列,并在目的地保持可达时被传递。
【讨论】:
如果 SSB 出现故障怎么办?还是网络连接消失了?使用 MSMQ,它仍将在本地写入,并且在连接恢复后将在公共队列中可用。如果网络连接中断,则无法将消息添加到 SSB 队列。 解决网络问题的方法是让所有通信服务器都有自己的数据库服务器。由于 SQL Server Express 支持 Service Broker,因此成本不会很高。以上是关于我应该使用 MSMQ 还是 SQL Service Broker 进行事务处理?的主要内容,如果未能解决你的问题,请参考以下文章
我应该使用 IntentService 还是 Service 进行 UI 更新?
Service 和 DAO 之间的关系应该是一对一还是一对多?
sql server 2008安装的时候选NT AUTHORITYNEWORK SERVICE 还是选 NT AUTHORITYSYSTEM ?