为 CQRS 实施包装 Masstransit 是一个好习惯吗? [关闭]
Posted
技术标签:
【中文标题】为 CQRS 实施包装 Masstransit 是一个好习惯吗? [关闭]【英文标题】:Is it a good practice to wrap Masstransit for CQRS implementation? [closed] 【发布时间】:2018-02-19 14:24:37 【问题描述】:我宁愿有一个单独的 CommandBus
和 EventBus
以及 ICommandHandler<TCommand>
和 IEventHandler<TCommand>
以便 OrderEventHandler
类看起来像:
public class OrderEventHandler :
IEventHandler<OrderPlaced>,
IEventHandler<OrderRegistrantAssigned>,
IEventHandler<OrderTotalsCalculated>,
IEventHandler<OrderConfirmed>,
IEventHandler<OrderExpired>,
IEventHandler<SeatAssignmentsCreated>,
IEventHandler<SeatAssigned>,
IEventHandler<SeatAssignmentUpdated>,
IEventHandler<SeatUnassigned>
public void Handle(OrderPlaced @event)...
.
.
.
一个可能的解决方案是在Masstransit
基础设施和我的CQRS
之间提供一个采用者(比如ConsumerToHandlerAdopter<T>
,它只公开我通常需要的上下文细节)。
但由于我是 Masstransit
的新手,我无法理解以后可能需要处理的问题。
所以我的问题是: 通常是否值得封装 Masstransit 以便我处理自己的基础架构?
【问题讨论】:
您是否使用消息队列/总线来同步读取模型和写入模型?你能在这里看看我的问题吗? softwareengineering.stackexchange.com/questions/378205/… +1。 鲍勃叔叔:不要嫁给框架!哦,你可以使用这个框架——只是不要耦合它。保持距离。将框架视为属于架构外圈之一的细节。不要让它进入内圈。 【参考方案1】:我们使用 MassTransit 广泛实施 CRQS,但仅用于命令处理。
多次讨论不使用消息传递基础架构来同步写入和读取模型的原因。主要原因是您有机会保持更改而不发布事件,因为这是两个不同的基础架构。除非你使用 DTC 之类的东西,否则你将无法保证模型之间的一致性。
此外,在这一点上,我们也更愿意远离“上帝处理程序”类。 MassTransit 特别擅长通过将每个消费者分离到一个单独的类来执行 SRP(单一责任原则)。
对于基于一般领域事件的集成(反应式事件处理),我们还使用 MassTransit。
您还可以拥有实现多个消息接口的事件,这样您将拥有更全面的事件处理:
public interface CustomerRegistered
string FullName get;
public interface OrderPlaced
string Reference get;
List<OrderLine> Lines get;
public class NewCustomerOrderedStuff : CustomerRegistered, OrderPlaced
...
public class CustomerRegisteredConsumer : IConsumer<CustomerRegistered>
public class OrderPlacedConsumer : IConsumer<OrderPlaced>
这些消费者中的每一个都会有不同的关注点,并且可以生活在单独的有界上下文(服务)中。
【讨论】:
感谢一百万 @Alexey Zimarev,我正在使用 rabbitmq 作为传输层。我的目标是在传奇中代表我的聚合,只要它们变得一致,然后通过调用aggregate.method()
发布返回的事件。聚合达到某种状态后我不需要它们,所以我可以删除它们。
我有几个项目使用 sagas 作为聚合。这工作得很好,但它没有单独的读写模型。同时,我为 EventStore github.com/alexeyzimarev/MassTransit.EventStoreIntegration 做了一个 saga 持久化,通过使用它,我可以拥有事件源 saga,使用投影构建读取模型,这些模型通过 EventStore 追赶订阅连接。
是的,在进行事件溯源时,拥有适当的事件存储非常重要。有些人为此目的使用无限期保留的 Kafka,但对此有不同的看法。当您使用事件溯源时,发布事件的问题会变得更糟,因为如果来自其他上下文的投影和事件消费者正在侦听同一总线,它将关闭重播事件的选项。
这是一种反应。这涉及将域事件转换为集成事件,并将它们写入集成流或将这些事件发布到某些消息总线。反应器消耗这些事件并在它们自己的有界上下文中产生必要的动作。您也可以将其称为“反应式 ACL”。
是的,这是一个潜在的问题,我对此没有真正的答案。我的观察是 RMQ 非常可靠。如果更改以事务方式持久化,然后我们将事件发布到总线,我们可以非常确定(尽管不是 100%)它确实发生了。我们运行 RMQ 多年,每天处理数百万条消息,从未遇到过问题。虽然这可能是网络问题,但在这种情况下,持久性也不起作用,除非它们位于完全不同的网络中。以上是关于为 CQRS 实施包装 Masstransit 是一个好习惯吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Masstransit队列以公共汽车为前缀,后缀为随机字符串