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

时间:2014-03-28 13:02:52

标签: c# event-handling domain-driven-design bounded-contexts easynetq

域驱动设计将事件传递到单独的有界上下文


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

我测试的内容:

  1. MVC:点火和忘记服务电话(异步) - >
  2. (IIS托管)收集数据并填充邮件的WCF - >
  3. 通过EasyNetQ / RabbitMQ ServiceBus发送 - >
  4. 该事件由订阅者(使用从WCF服务端点初始化的DI容器)使用,该容器处理事件&它的数据。
  5. 我做了一些测试,看看如果通过在MVC端循环来快速调用服务它是如何工作的

    for (int i = 0; i < 200; i++)
    {
            ...
            client.MyServiceMethod(someId, startDate); 
            ...
    }
    

    MessageQueue部分是快速的,基于它被发送到队列并在同一秒内由订户接收的时间戳。循环通过WCF服务调用非常慢。循环它们需要几秒钟。我尝试从wsHttpBinding切换到netTcpBinding,并在WCF中使用serviceThrottling。

    WCF不是强制性的,但似乎一个单独的事件处理项目(在发布者端)将是有益的,并且可以物理地位于MVC应用程序的其他地方(负载减少等)。对于这种情况,WCF是否合理,或者我应该尝试使用Windows服务或其他一些自托管的服务。控制台应用程序等,或者可能使用MVC中的线程来生成事件数据,还是有更好的场景?这类事件处理系统的最佳实践是什么?基本上似乎生成事件数据的东西是有益的,因为它必须在某处处理,同时不会减慢最终用户正在使用的UI。

2 个答案:

答案 0 :(得分:2)

我认为您应该使用像NServiceBus(非免费)或MassTransit(免费)这样的工具,而不是尝试像这样尝试自己的基础设施。 (我会考虑这个最佳做法。)

我无法代表MassTransit,但我对NServiceBus的体验非常好。您只需指定哪些消息转到哪个队列。您可以使用几种不同的排队技术,但我建议从默认的MSMQ实现开始。不需要WCF配置噩梦。 ;)

所有的消息处理程序也将自动封装在分布式事务中,这样,如果数据库交互失败,整个消息将被回滚,您将来可以再次尝试该消息。 / p>

答案 1 :(得分:2)

如果我表现良好,您的事件创建过程“很重”,并且您希望避免在MVC过程中创建。我猜你正在向WCF服务发送一些信息,以便让他准备活动。

你可以想到避免WCF步骤的2个消费者场景:

  1. 您的MVC应用程序创建并发布一个“轻量级”事件,其中包含创建“重”事件所需的所有数据(基本上是您将传递给WCF的输入数据)
  2. EventCreator订阅者使用此消息并准备重大事件
  3. 您现有的消费者将消耗沉重的事件
  4. EasyNetQ已经提供了发布和使用消息的简单功能。 您在网上找到的大多数教程都建议使用TopShelf在控制台应用程序(调试)或Windows服务(生产)中托管您的消费者。 EasyNetQ在这里有一个例子:EasyNetQ with TopShelf

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