基于事件的集成与版本化事件

问题描述

我想使用事件传达我的服务。我将发布(内部)我的所有域事件,并允许其他任何服务订阅它们。但是这种方法将这些服务结合在一起。我不再被允许更改我的活动。这甚至比本地耦合更糟糕,因为我不再知道我的消费者了。这将开发/重构的能力限制为不可接受的指令。我正在考虑对事件进行版本控制,以解决大多数问题。但是如何订阅版本化事件?引入将所有事件的版本进行分组,然后将侦听器中的下播事件分组为已接受的通用接口,听起来并不重要。我还考虑将事件的所有受支持版本发布到总线。根据定义,每个订阅者只能处理一个版本。我不希望我的领域介入此事,因此我需要构建一种基础结构侦听器,以将捕获的事件转换为其他版本。我在互联网上找不到关于该主题的任何信息,这自动使我想起我是否完全没有错:)

更新:经过深思熟虑,我不再想要发布域事件。我认为将内部服务机制暴露给外部世界是不可取的。它还可能违反某些域数据访问限制。我认为,解决方法是将域事件映射到其他一些更容易整合的事件。但我仍然可能需要对它们进行扭曲处理:)

UPDATE2:经过一番协商,提出了一个想法。假设我们坚持集成事件的概念。可以将此类事件视为类型和事件ID。因此,外部侦听器仅关注事件类型。如果发生事件,则将为侦听器提供事件ID。这使侦听器可以从给定版本的stream / bus / wtf中获取真实事件。例如$eventsstore->get($eventGuid,$eventType,'v27')PHP语法)

解决方法

我将(内部)发布我的所有域事件,并允许其他任何服务订阅它们。

这是偶驱动架构中的常见模式。我假设您将事件发布在事件代理上,例如Apache Kafka和消费者都订阅了Event Broker上的主题。

我不再被允许更改我的活动。这甚至比本地耦合更糟糕,因为我不再知道我的消费者了。这将开发/重构的能力限制到不可接受的程度。我正在考虑对事件进行版本控制,以解决大多数问题。

不,已发布的合同应进行版本控制,并且不能向后添加任何向后兼容的更改。如果您需要与向后兼容的更改,则必须引入新版本的已发布合同-并在有消费者的情况下保留旧版本。这与基于REST的界面没有什么不同-您必须履行合同。

使用REST,您可以同时使用/v1/orders/v2/orders来完成此操作。对于事件驱动的架构,您可以使用两个 topics 主题,例如orders-v1orders-v2-这两个包含 schema 之后的数据,例如Avro

在事件驱动的架构中,服务是分离的(中间有一个代理),如果您添加了一个较小的转换器,例如,您实际上可以逐步淘汰旧的生产者。消耗orders-v2并将事件转换为旧格式,然后将其发布到orders-v1上,因此v1v2都仍被发布。

Building Event-Driven Microservices是一本很好的书。