用于将数据同步到其他微服务的领域事件
Domain Events for syncing data to other microservices
我正在尝试了解有关 DDD
的更多信息,并且正在经历 DomainEvents
。假设我们有三个微服务 Service A
、Service B
和 Service 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
=]
我遇到的领域事件指南:
- 不要将多余的信息作为
DomainEvent
数据的一部分共享。
- 当
consuming BoundedContext
知道 Producing BoundedContext
时可能会分享 Id 否则会分享完整信息
- 不要使用
DomainClasses
表示事件中的数据
- 对
Events
中的数据使用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
?
或者我可以只创建一个名为 FooChanged
的 DomainEvent
并采用 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.
您在集成事件中发送什么信息,这真的取决于。您有以下选择:
发布FooNameChanged
、FooEmailChanged
等活动,只有Id
个Foo
。在这种情况下,如果您的消费者需要有关 更改内容的更多信息,他们将需要调用您的服务(可能是 REST API 调用)。这种方法的一个缺点是,如果您的活动有很多订阅者,那么所有这些服务将几乎同时调用您的服务以获取活动的详细信息。
使用消费服务可能需要的完整数据发布事件(请注意,它与您的域不同),例如 PerviousValue
、CurrentValue
等。如果您的有效负载不是很大,这可能是一个不错的选择。这些类型的事件通常称为“FAT 事件”
我正在尝试了解有关 DDD
的更多信息,并且正在经历 DomainEvents
。假设我们有三个微服务 Service A
、Service B
和 Service 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
=]
我遇到的领域事件指南:
- 不要将多余的信息作为
DomainEvent
数据的一部分共享。 - 当
consuming BoundedContext
知道Producing BoundedContext
时可能会分享 Id 否则会分享完整信息 - 不要使用
DomainClasses
表示事件中的数据 - 对
Events
中的数据使用
Primitive types
现在由于指南冲突而出现的问题:
Does it mean that I should fire two different events when they change like
FooNameChange
andFooEmailChanged
and only use theid
along with theupdated value
as part of theEvent Payload
?
或者我可以只创建一个名为 FooChanged
的 DomainEvent
并采用 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.
您在集成事件中发送什么信息,这真的取决于。您有以下选择:
发布
FooNameChanged
、FooEmailChanged
等活动,只有Id
个Foo
。在这种情况下,如果您的消费者需要有关 更改内容的更多信息,他们将需要调用您的服务(可能是 REST API 调用)。这种方法的一个缺点是,如果您的活动有很多订阅者,那么所有这些服务将几乎同时调用您的服务以获取活动的详细信息。使用消费服务可能需要的完整数据发布事件(请注意,它与您的域不同),例如
PerviousValue
、CurrentValue
等。如果您的有效负载不是很大,这可能是一个不错的选择。这些类型的事件通常称为“FAT 事件”