2

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


MVC 中的用户操作应生成一个事件,该事件将传递给远程(同一 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 切换到 netTcpBinding,并在 WCF 中使用 serviceThrottling。

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

4

2 回答 2

2

我认为您最好使用NServiceBus(非免费)或MassTransit (免费)之类的工具,而不是尝试像这样推出自己的基础架构。(我会考虑这个最佳实践。)

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

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

于 2014-03-28T22:44:30.973 回答
2

如果我理解得好,您的事件创建过程是“繁重的”,并且您希望避免在 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 容器

于 2014-04-17T10:01:30.773 回答