持久性消息传递/服务总线 - 自己动手或冒险学习曲线?
-
06-07-2019 - |
题
我们有一个客户端应用程序需要向服务器发送消息以进行各种通知。为了使客户端可以偶尔运行,我将采用消息队列方法。队列处理将从队列中取出消息并调用Web服务,将其置于另一个队列中以最终进行处理。这个问题是关于客户环境的;服务器环境已经确定。
我不想使用MSMQ,因为我们无法控制所有客户端PC以正确安装/配置和保护MSMQ,并且由于调查内容的工具质量,支持更具挑战性MSMQ队列。 SQL Server 2005 Express位于所有计算机上,用于存储应用程序的数据。
我目前有两个选项:
- 编写一个相当基本的持久性消息队列,在序列化后将消息存储在表中,然后使用
ThreadPool.QueueUserWorkItem
让它们由针对每种消息类型配置的处理程序处理。全部在System.Transactions.TransactionScope
中,因此只有在成功处理它们时才会从持久队列中删除它们。 - 使用NServiceBus(这是我们作为一个团队使用的服务总线,因此MassTransit等不是选项)在客户端上,使用本地数据库的Service Broker传输。 醇>
我对服务总线的经验不多(我还没有真正得到服务总线的术语)所以我更关心学习曲线,而不是写一些更简单的东西,以我需要的方式满足我的要求(部署是一个大考虑因素。)
有没有人有任何想法?
解决方案 3
最后,我编写了一个使用我自己的SqlTransport配置的基本消息总线,以便在引发事件并发出单独的线程来处理消息之前,将消息序列化并保存到SQL Server数据库表中。
其他提示
好吧,我不知道我会建议MSMQ,但我会建议有很多边缘情况需要考虑'滚动你自己'。
即使使用线程池方法,请注意,如果您关心可能存在排序问题 - 由于线程池的处理方式,顺序发布到线程池的两个项可能不按顺序执行工作项目。
您还需要考虑邮件的持久性,邮件存在的时间,如何检测“致命”的未送达状态以及在这种情况下该怎么做。
在应用程序在排队消息的同时发生故障的情况下,还存在许多潜在的边缘情况 - 例如,它可能无法确认消息已排队,即使它已经排队。是的,你可以确认队列确认,但你可以无休止地进入ack圈......
为什么不让应用程序检测到它何时连接,并在那时发送所有数据?
编写了我们自己的服务总线后,我可以告诉你这不是一项微不足道的工作,你将遇到所有其他实施者已经遇到的相同边缘情况。 kyoryu提出了两个非常重要的。
你是否自己动手也取决于你内部掌握的技能,并且将来会保持解决方案。
另一个考虑因素是系统的最终规模及其可靠性要求。内部解决方案是否会充分扩展?
我们的点对点消息总线Zebus,基于ZeroMq(传输),Cassandra(对等发现和持久性)和Protobuf(序列化)。
- 在客户端上没有客户端部署它只是一个库
- 使用Cassandra提供消息持久性并处理许多不同的边缘情况(这在我们的生产环境中定期测试)
- 它表现良好,因为它是无代理解决方案,没有单一的性能瓶颈
- 没有单点故障,因为目录可以与可用的数据存储一起使用,例如Cassandra 醇>
它是开源和生产测试 https://github.com/Abc-Arbitrage/Zebus一>