【问题标题】:Distribute events over the network通过网络分发事件
【发布时间】:2021-09-03 19:00:36
【问题描述】:

我正在尝试将 Axon 框架用于基于事件溯源的应用程序,并且我需要发布某些类型的事件,以便其他服务可以出于特定目的(统计、电子邮件服务等)意识到这一点。问题是,根据 Axon 的文档,服务应该共享事件存储以订阅这些事件(请参阅here)。这违反了微服务架构,因为服务共享数据库,尽管架构不会随着时间而改变,因为它是一个事件存储。另一种选择是设置 Kafka 或其他消息代理,如 RabbitMQ、ActiveMQ 或任何其他与 AMQP 兼容的代理。但是,这意味着这些消息代理也将负责在事件中持久化,这并不理想。我的问题是:有没有办法将事件保存在非共享数据存储中,同时将事件发布到主题或队列中的另一个服务?

谢谢。

【问题讨论】:

  • 由于我回答的互动,回到这个问题后,我又看了你的问题。我完全同意所引用的部分提供了与当前应用程序开发标准相冲突的错误信息。因此,我在参考指南中添加了一个问题,以相应地更新本节。就这是否正义而言,为此道歉,托马斯。提交更新后我会尽快回复。如果您有兴趣,可以在这里找到问题 - github.com/AxonIQ/reference-guide/issues/225
  • 嗨史蒂文,感谢您照顾这个。没有必要道歉,这是一个技术讨论,它非常有用。希望我们可以帮助改进 Axon。是否可以查看事件存储的源代码还是私有的?
  • Axon Server 标准版是开源的,可以在这里查看(github.com/AxonIQ/axon-server-se)。包含 RAFT 以实现分布式共识的企业版已关闭。这意味着 RAFT 细节不可见。不过,存储解决方案是 Axon Server Standard 的一部分,因此您绝对可以在那里查看。我相信您已经找到了存储库,我基于您构建的这个问题 - github.com/AxonIQ/axon-server-se/issues/390
  • 只是想告诉大家这个问题中提到的“分发事件”部分已经更新。因此,所描述的困境应该得到解决,尽管在概念上是正确的。

标签: cqrs event-sourcing axon axon-framework


【解决方案1】:

您是正确的,在服务之间共享数据库会违反 SOA 的原则,从而违反微服务的原则。令人惊讶的是,他们在文档中提出了这一建议。

这是我采用的一种方法,对您的设置进行了一些假设:通过 http 端点 (API) 将 Event Store 中的事件公开给外部消费者。 API 可能允许过滤来自某个检查点/日期的事件,也可以通过流/聚合 Id 过滤。然后使用消息代理或 ESB 广播通知事件,这与事件存储事件不同,只包含足够的信息来提醒下游服务发生了某些变化,以便它们可以查询 API。顺序如下:

  1. 对 WidgetA 进行了更改
  2. Main Service 广播一条消息,WidgetA 在 XX 日期发生了变化
  3. Consuming Service 接收到 WidgetChangedEvent
  4. Consuming Service 向 Main Service 的 API 查询 WidgetA 的 Id 晚于 XX 日期的事件

【讨论】:

  • 我正在考虑摆脱 Axon 并开始使用 DynamoDB 作为事件存储,因为它确实让我可以将事件自动保存并广播到其他服务(当然也可以广播到同一进程) .挑战是重播数据存储中的所有事件并管理快照,但无论如何......
  • 如果您正在考虑摆脱 Axon,我建议您结合使用 Akka Persistence(以针对重放优化的模式处理将事件写入数据库,以及管理快照) 和 Akka Persistence Query 在事件进入消息队列时发布事件以进行服务间/上下文间通信。
【解决方案2】:

需要考虑的关键是,在微服务环境中,一些服务确实属于相同的上下文,而其他服务则不属于。 那些这样做的,在概念上将是相同(有界)上下文的一部分。 此外,上下文中的服务也可以被视为单个服务。从这个角度来看,共享数据源/模式应该没有问题。

只要范围扩大并且你有不同的上下文,我假设你的设置中就有了,Tomás,然后你会为你的事件引入某种广播机制。

真正使用事件溯源的系统的理想选择是实际的事件存储。因此,Axon Server(或EventStore.com)将是您唯一合理的选择,因为它们是事件存储数据库类型。 Axon Server 还提供了定义我刚才提到的上下文的方法,以自动构建不同的存储位置和消息流以保持数据分离。

提到的文档在涉及 Axon 服务器时有一些不吉利的措辞,我必须承认这一点。我敢打赌对文档进行了一些调整以减轻这种混乱。

谈到EmbeddedEventStore,我假设您正在使用它,我想澄清以下内容。您应该认为,尽管数据源是共享的,但没有任何说明该数据源应包含您的应用程序特定模式。实际上,建议仅使用您的事件的不同数据源。正如您已经提到的,这不会形成问题,因为这样做时不需要担心模式混合。你会设置这个。根据(前面提到的)上下文。因为您绝对不希望将不同上下文之间的事件组合在一起。正是有了这种设置,以及将事件分发到其他上下文的要求,才能使用替代方案(从 Axon 服务器等专用消息路由器的角度来看)AMQP 或 Kafka。

我仍然同意这不是理想的解决方案;这将是一个专门的事件存储实现,如 Axon Server。所以,让我参考一下您在留言中提出的问题:

有没有办法将事件保存在非共享数据存储中,同时将事件发布到主题或队列中的另一个服务?

是的,有。理想情况下,您会使用像 Axon Server 这样的专用 Event Store。或者严格控制上下文分离的单一用途数据源和代理的组合。

由于您已经在使用 Axon Framework,但试用 Axon Server 应该是小菜一碟,所以我会采取这条路线。

【讨论】:

  • 如果您在回答中推荐产品,并且尤其是如果您声称它只是两个合理选择之一,您绝对应该披露您与该产品的任何关系.您的个人资料表明您是 Axon 框架的首席开发人员。
  • 我认为可以通过查看我的个人资料来明确这一点,正如您也发现的那样。补充,注意 Axon Server 是免费使用的。从这个角度来看,我会同时考虑 Axon Framework 和 Axon Server 产品。无论如何,如果我错过了有关此事的行为准则,我深表歉意;只是想从 Axon Framework 的角度分享预期的观点。希望从我的回复中仍然清楚。如果没有,请告诉我您的期望,我会更新我的回复。
  • 嗨史蒂文。如果限界上下文是不同的微服务,则它们并不意味着使用相同的数据库。对于单个有界上下文或子域,我们可能有 20 个微服务。即使同一个团队处理有界上下文的微服务,也不应共享数据库。即使我没有在事件存储中保存特定的模式,这是系统中的一个关键点,不应该共享。应该提供其他机制,比如 dynamo 流甚至 mongo 订阅更改
  • 我同意,有界上下文之间你不会共享源代码。但是有限的上下文中,老实说,我不会预见到共享的直接问题。这至少是我试图在我的回答中表达的观点。如果有部分不清楚这一事实,请告诉我(以便我可以调整措辞)。请注意,尽管关于数据库的论点仍然成立,但 Event Store 的概念角色在此完全不同。为了正确支持事件溯源,最重要的是使用这样的源,最好是专用的事件存储实现。
猜你喜欢
  • 1970-01-01
  • 2012-02-03
  • 2015-06-23
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 2013-08-21
  • 1970-01-01
相关资源
最近更新 更多