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

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

我目前有两个选项:

  1. 编写一个相当基本的持久性消息队列,在序列化后将消息存储在表中,然后使用 ThreadPool.QueueUserWorkItem 让它们由针对每种消息类型配置的处理程序处理。全部在 System.Transactions.TransactionScope 中,因此只有在成功处理它们时才会从持久队列中删除它们。
  2. 使用NServiceBus(这是我们作为一个团队使用的服务总线,因此MassTransit等不是选项)在客户端上,使用本地数据库的Service Broker传输。
  3. 我对服务总线的经验不多(我还没有真正得到服务总线的术语)所以我更关心学习曲线,而不是写一些更简单的东西,以我需要的方式满足我的要求(部署是一个考虑因素。)

    有没有人有任何想法?

有帮助吗?

解决方案 3

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

其他提示

好吧,我不知道我会建议MSMQ,但我会建议有很多边缘情况需要考虑'滚动你自己'。

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

您还需要考虑邮件的持久性,邮件存在的时间,如何检测“致命”的未送达状态以及在这种情况下该怎么做。

在应用程序在排队消息的同时发生故障的情况下,还存在许多潜在的边缘情况 - 例如,它可能无法确认消息已排队,即使它已经排队。是的,你可以确认队列确认,但你可以无休止地进入ack圈......

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

编写了我们自己的服务总线后,我可以告诉你这不是一项微不足道的工作,你将遇到所有其他实施者已经遇到的相同边缘情况。 kyoryu提出了两个非常重要的。

你是否自己动手也取决于你内部掌握的技能,并且将来会保持解决方案。

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

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

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

scroll top