基于事件的版本化事件集成
Event based integration with versioned events
我想使用事件来传达我的服务。我将(在内部)发布我所有的领域事件,并允许任何其他服务订阅它们。但是这种方法将这些服务结合在一起。我不再被允许更改我的事件。这比本地耦合更糟糕,因为我不再了解我的消费者了。这将 developing/refactoring 的能力限制在不可接受的范围内。我正在考虑对我的事件进行版本控制,这可以解决大部分问题。但是如何订阅版本化事件呢?引入对所有事件版本进行分组的通用接口,然后将侦听器中的事件向下转换为可接受的版本,这听起来不像是一个重要的解决方案。我还考虑将事件的所有支持版本发布到总线。根据定义,每个订阅者将只处理一个版本。我不希望我的域参与到这个问题中,所以我需要构建一种基础架构侦听器,将捕获的事件转换为其他版本。我在 Internet 上找不到关于该主题的任何内容,如果我没有完全错的话,这会自动让我思考 :)
更新:经过深思熟虑,我不想再发布我的领域事件。我认为将内部服务机制暴露给外部世界是不可取的。它还可能违反某些域数据访问限制。我认为,要走的路是将我的领域事件映射到一些更复杂的集成事件。但我可能仍然需要一些方法来改变它们:)
更新 2:经过一些协商,一个想法出现了。假设我们坚持整合事件的概念。此类事件可被视为类型和事件 ID。所以外部监听器只关注事件类型。如果事件发生,则将向侦听器提供事件 ID。这使侦听器能够从给定版本的 stream/bus/wtf 中获取真实事件。 $eventsStore->get($eventGuid, $eventType, 'v27')
例如(PHP 语法)
I gonna publish (internally) all my domain events and allow any other service to subscribe to them.
这是 Even-Driven 架构中的常见模式。我假设您在事件代理上发布事件,例如Apache Kafka 和消费者订阅事件代理上的主题。
I am not longer allowed to change my events. This is even worse than local coupling because I don't event know my consumers any more. This limits the ability of developing/refactoring to unacceptable degree. I am thinking about versioning my events which solves most of the issues.
不,已发布的合同 应该进行版本控制,不能向它们添加向后兼容的更改。如果您需要不向后兼容的更改,则必须引入新版本的 已发布合约 - 只要有消费者,就保留旧版本。这与 REST-based 接口没有什么不同 - 你必须履行你的合同。
使用 REST,您可以同时使用 /v1/orders
和 /v2/orders
来完成此操作。对于 Event-Driven 架构,您使用两个 主题 例如orders-v1
和 orders-v2
- 这两个包含遵循 模式 的数据,例如Avro.
在 Event-Driven 架构中,服务是解耦的(中间有一个代理),如果你添加一个更小的转换器,你实际上可以逐步淘汰旧的生产者,例如使用 orders-v2
并将事件转换为旧格式并将它们发布到 orders-v1
- 因此 v1
和 v2
仍然发布。
Building Event-Driven Microservices 是一本关于这方面的好书。
我想使用事件来传达我的服务。我将(在内部)发布我所有的领域事件,并允许任何其他服务订阅它们。但是这种方法将这些服务结合在一起。我不再被允许更改我的事件。这比本地耦合更糟糕,因为我不再了解我的消费者了。这将 developing/refactoring 的能力限制在不可接受的范围内。我正在考虑对我的事件进行版本控制,这可以解决大部分问题。但是如何订阅版本化事件呢?引入对所有事件版本进行分组的通用接口,然后将侦听器中的事件向下转换为可接受的版本,这听起来不像是一个重要的解决方案。我还考虑将事件的所有支持版本发布到总线。根据定义,每个订阅者将只处理一个版本。我不希望我的域参与到这个问题中,所以我需要构建一种基础架构侦听器,将捕获的事件转换为其他版本。我在 Internet 上找不到关于该主题的任何内容,如果我没有完全错的话,这会自动让我思考 :)
更新:经过深思熟虑,我不想再发布我的领域事件。我认为将内部服务机制暴露给外部世界是不可取的。它还可能违反某些域数据访问限制。我认为,要走的路是将我的领域事件映射到一些更复杂的集成事件。但我可能仍然需要一些方法来改变它们:)
更新 2:经过一些协商,一个想法出现了。假设我们坚持整合事件的概念。此类事件可被视为类型和事件 ID。所以外部监听器只关注事件类型。如果事件发生,则将向侦听器提供事件 ID。这使侦听器能够从给定版本的 stream/bus/wtf 中获取真实事件。 $eventsStore->get($eventGuid, $eventType, 'v27')
例如(PHP 语法)
I gonna publish (internally) all my domain events and allow any other service to subscribe to them.
这是 Even-Driven 架构中的常见模式。我假设您在事件代理上发布事件,例如Apache Kafka 和消费者订阅事件代理上的主题。
I am not longer allowed to change my events. This is even worse than local coupling because I don't event know my consumers any more. This limits the ability of developing/refactoring to unacceptable degree. I am thinking about versioning my events which solves most of the issues.
不,已发布的合同 应该进行版本控制,不能向它们添加向后兼容的更改。如果您需要不向后兼容的更改,则必须引入新版本的 已发布合约 - 只要有消费者,就保留旧版本。这与 REST-based 接口没有什么不同 - 你必须履行你的合同。
使用 REST,您可以同时使用 /v1/orders
和 /v2/orders
来完成此操作。对于 Event-Driven 架构,您使用两个 主题 例如orders-v1
和 orders-v2
- 这两个包含遵循 模式 的数据,例如Avro.
在 Event-Driven 架构中,服务是解耦的(中间有一个代理),如果你添加一个更小的转换器,你实际上可以逐步淘汰旧的生产者,例如使用 orders-v2
并将事件转换为旧格式并将它们发布到 orders-v1
- 因此 v1
和 v2
仍然发布。
Building Event-Driven Microservices 是一本关于这方面的好书。