MVC - WCF - RabbitMQ -域事件通过消息队列到消费者加速或替代
本文关键字:消费者 加速 队列 RabbitMQ WCF 事件 MVC 消息 | 更新日期: 2023-09-27 17:54:22
领域驱动设计传递事件以分离有界上下文
MVC中的用户操作应该生成一个Event,该Event传递给远程(相同的LAN)事件处理程序。
我测试了什么:
- MVC:即发即弃服务调用(异步)->
- (IIS托管)收集数据并填充消息的WCF ->
- 通过EasyNetQ/RabbitMQ ServiceBus发送->
- 事件由处理事件的订阅者(使用从WCF服务端点初始化的DI容器)消费;它的数据。
我做了一些测试,看看它是如何工作的,如果服务被调用相当快的循环在MVC端
for (int i = 0; i < 200; i++)
{
...
client.MyServiceMethod(someId, startDate);
...
}
MessageQueue部分是快速的,基于它被发送到队列并在同一秒内被订阅者接收的时间戳。遍历WCF服务调用的速度非常慢。循环遍历它们需要很多秒。我尝试从wsHttpBinding切换到netttcpbinding,并在WCF中使用serviceThrottling。
WCF不是强制性的,但它似乎是一个单独的事件处理项目(在发布者端)将是有益的,可以从MVC应用程序的物理位置(减少负载等)。WCF是否适用于这种情况,或者我是否应该尝试使用Windows服务或其他自托管的应用程序,例如控制台应用程序等,或者可能使用MVC中的线程来生成事件数据,或者有更好的场景?这种类型的事件处理系统的最佳实践是什么?基本上,似乎有一些东西生成事件数据是有益的,因为它必须在某个地方处理,而不会减慢最终用户正在使用的UI
与其尝试像这样运行您自己的基础设施,我认为您最好使用NServiceBus(非免费)或MassTransit(免费)这样的工具。(我认为这是最佳实践。)
我不能代表MassTransit,但我使用NServiceBus的经验非常好。您只需要指定哪些消息将发送到哪个队列。您可以使用几种不同的排队技术,但我建议从默认的MSMQ实现开始。不需要WCF配置噩梦。;)
您的所有消息处理程序也将自动包装在分布式事务中,以便如果DB交互失败,整个消息将被回滚,并且您将能够在将来再次尝试消息。
如果我理解得好,你的事件创建过程是"沉重的",你想避免在MVC过程中创建。我猜你是在向WCF服务发送一些信息,以便让他准备活动。
您可以考虑一个避免WCF步骤的2个消费者场景:
- 您的MVC应用程序创建并发布一个"轻"事件,其中包含创建"重"事件所需的所有数据(基本上是您将传递给WCF的输入数据)
-
EventCreator
用户接收此消息并准备重事件 - 你已经存在的消费者将消耗重事件
EasyNetQ已经提供了发布和使用消息的简单函数。您在网上找到的大多数教程都建议使用TopShelf在控制台应用程序(调试)或windows服务(生产)中托管您的消费者。EasyNetQ有一个例子:EasyNetQ with TopShelf
如果你想"隐藏"你的MVC项目上的EasyNetQ依赖,你可以包装EasyNetQ IBus
到一个自定义的Bus
,并使用一个IoC容器来注入你的总线的特定实现。上面提供的示例使用Castle.Windsor
作为IoC容器