MVC - WCF - RabbitMQ -域事件通过消息队列到消费者加速或替代



领域驱动设计传递事件以分离有界上下文


MVC中的用户操作应该生成一个Event,该Event传递给远程(相同的LAN)事件处理程序。

我测试了什么:

  1. MVC:即发即弃服务调用(异步)->
  2. (IIS托管)收集数据并填充消息的WCF ->
  3. 通过EasyNetQ/RabbitMQ ServiceBus发送->
  4. 事件由处理事件的订阅者(使用从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个消费者场景:

  1. 您的MVC应用程序创建并发布一个"轻"事件,其中包含创建"重"事件所需的所有数据(基本上是您将传递给WCF的输入数据)
  2. EventCreator用户接收此消息并准备重事件
  3. 你已经存在的消费者将消耗重事件

EasyNetQ已经提供了发布和使用消息的简单函数。您在网上找到的大多数教程都建议使用TopShelf在控制台应用程序(调试)或windows服务(生产)中托管您的消费者。EasyNetQ有一个例子:EasyNetQ with TopShelf

如果你想"隐藏"你的MVC项目上的EasyNetQ依赖,你可以包装EasyNetQ IBus到一个自定义的Bus,并使用一个IoC容器来注入你的总线的特定实现。上面提供的示例使用Castle.Windsor作为IoC容器

相关内容

  • 没有找到相关文章

最新更新