6

我们有一个客户端应用程序需要向服务器发送消息以获取各种通知。为了客户端可以偶尔连接运行,我将使用消息队列方法。队列处理将从队列中取出消息并调用 Web 服务,该服务会将它们放在另一个队列中以最终进行处理。这个问题是关于客户端环境的;服务器环境已经确定。

我不想使用 MSMQ,因为我们无法控制所有客户端 PC 以正确安装/配置和保护 MSMQ,而且由于用于调查 MSMQ 队列内容的工具质量,支持更具挑战性. SQL Server 2005 Express 在所有机器上,用于为我们的应用程序存储数据。

我目前有两个选择:

  1. 编写一个相当基本的持久消息队列,在序列化消息后将消息存储在表中,然后使用ThreadPool.QueueUserWorkItem针对每种消息类型配置的处理程序处理它们。总之,System.Transactions.TransactionScope如果它们被成功处理,它们只会从持久队列中删除。
  2. 在客户端上使用 NServiceBus(这是我们作为一个团队使用的服务总线,因此 MassTransit 等不是选项),以及使用本地数据库的 Service Broker 传输。

我对服务总线几乎没有经验(我仍然没有真正了解服务总线术语),因此与编写更简单的东西以我需要的方式满足我的要求相比,我担心学习曲线(部署是一个考虑)。

有人有想法吗?

4

3 回答 3

2

好吧,我不知道我会推荐 MSMQ,但我会建议有很多边缘案例需要考虑“自己动手”。

即使使用线程池方法,请注意,如果您关心,可能存在排序问题 -由于线程池处理工作项的方式,顺序发布到线程池的两个项目可能不会按顺序执行。

您还需要考虑消息的持久性,它们应该存在多长时间,如何检测“致命”未传递状态,以及在这种情况下该怎么做。

在您的应用程序在排队消息的同时出现故障的情况下也有许多潜在的边缘情况 - 例如,它可能不会得到消息已排队的确认,即使它是。是的,您可以确认队列确认,但您可以无休止地进入确认圈......

为什么不让应用程序检测它何时连接,并在那时发送所有数据?

于 2009-12-23T23:48:45.567 回答
2

编写了我们自己的服务总线后,我可以告诉您这不是一件容易的事,您将遇到所有其他实施者已经遇到的相同边缘情况。kyoryu 提出了两个非常重要的问题。

您是否自行开发还取决于您在内部拥有的技能,以及将来维护解决方案的技能。

另一个考虑因素是系统的最终规模及其可靠性要求。内部解决方案能否充分扩展?

我们的点对点消息总线 Zebus,基于 ZeroMq(传输)、Cassandra(点发现和持久性)和 Protobuf(序列化)。

  1. 没有客户端部署,因为在客户端它只是一个库
  2. 消息持久性也使用 Cassandra 提供,并处理许多不同的边缘情况(这在我们的生产环境中定期测试)
  3. 它表现良好,因为它是一个无代理解决方案,所以没有单一的性能瓶颈
  4. 没有单点故障,因为目录可以与可用的数据存储(例如 Cassandra)一起使用

它是开源和生产测试的https://github.com/Abc-Arbitrage/Zebus

于 2016-05-13T08:31:46.043 回答
0

最后,我编写了一个使用我自己的 SqlTransport 配置的基本消息总线,以便在引发事件并通知单独的线程来处理消息之前将消息序列化并保存到 SQL Server 数据库表中。

于 2009-10-13T11:10:46.370 回答