用于将数据同步到其他微服务的领域事件

Domain Events for syncing data to other microservices

我正在尝试了解有关 DDD 的更多信息,并且正在经历 DomainEvents。假设我们有三个微服务 Service AService BService C

Service A 有一个实体 Foo 定义如下:

public class Foo : AggregateRoot
{
    public string id {get; private set;}

    public string name {get; private set;}

    public string email {get; private set;}
}

Service B 是一项服务,它依赖于 Foo 中的 email,而 Service C 依赖于 [=17= 中的 name ] 并且只要 Foo 的值通过 Bus.[=47 发生变化,数据就会从 Service A 复制到 Service B 并复制到 Service C =]

我遇到的领域事件指南:

  1. 不要将多余的信息作为 DomainEvent 数据的一部分共享。
  2. consuming BoundedContext 知道 Producing BoundedContext 时可能会分享 Id 否则会分享完整信息
  3. 不要使用DomainClasses表示事件中的数据
  4. Events
  5. 中的数据使用Primitive types

现在由于指南冲突而出现的问题:

Does it mean that I should fire two different events when they change like FooNameChange and FooEmailChanged and only use the id along with the updated value as part of the Event Payload?

或者我可以只创建一个名为 FooChangedDomainEvent 并采用 Foo 的状态将其序列化并触发事件。然后编写一个处理程序作为同一 BoundedContext 的一部分,它将获取数据并将其放在 Bus 上,用于订阅消息的任何服务,并且各个服务根据Id 已附加和事件 arg(更新的数据)。

DomainEvents不是补丁文件

也就是说,我们并不是要创建通用目的的更改描述,而是要使我们的消息与我们理解的领域概念保持一致。

因此,无论两个更改属于同一事件还是不同事件,都会有很大的影响 "it depends"。

如果您需要跨服务对话,您或许应该寻找集成事件而不是“领域事件” 来自微软 Docs

Domain events versus integration events

Semantically, domain and integration events are the same thing: notifications about something that just happened. However, their implementation must be different. Domain events are just messages pushed to a domain event dispatcher, which could be implemented as an in-memory mediator based on an IoC container or any other method.

On the other hand, the purpose of integration events is to propagate committed transactions and updates to additional subsystems, whether they are other microservices, Bounded Contexts or even external applications. Hence, they should occur only if the entity is successfully persisted, otherwise it's as if the entire operation never happened.

As mentioned before, integration events must be based on asynchronous communication between multiple microservices (other Bounded Contexts) or even external systems/applications.

Thus, the event bus interface needs some infrastructure that allows inter-process and distributed communication between potentially remote services. It can be based on a commercial service bus, queues, a shared database used as a mailbox, or any other distributed and ideally push based messaging system.

您在集成事件中发送什么信息,这真的取决于。您有以下选择:

  • 发布FooNameChangedFooEmailChanged等活动,只有IdFoo。在这种情况下,如果您的消费者需要有关 更改内容的更多信息,他们将需要调用您的服务(可能是 REST API 调用)。这种方法的一个缺点是,如果您的活动有很多订阅者,那么所有这些服务将几乎同时调用您的服务以获取活动的详细信息。

  • 使用消费服务可能需要的完整数据发布事件(请注意,它与您的域不同),例如 PerviousValueCurrentValue 等。如果您的有效负载不是很大,这可能是一个不错的选择。这些类型的事件通常称为“FAT 事件”