在使用事件源的分布式系统中,在哪里存储事件?
假设您有多个系统,这些系统通过事件集成,并且所有系统都使用事件源。您将事件存储在哪里?
就我而言,我有三个系统:
- 一个网站,它是一家商店
- 网站的后端,用于管理客户、产品等
- 一个会计系统
每当这些系统之一发生域事件时,该事件就会被发布并可以由其他系统。所有系统都使用事件源。
我想知道你会在哪里保存事件。当然,每个系统都必须存储它处理的所有事件,因为它使用事件源,因此取决于它曾经处理过的事件。
但是那些不需要的、因此系统没有订阅的其他事件呢?我正在努力应对需求可能发生变化的事实,这样系统就必须处理过去未持续存在的事件。如果系统需要处理发生时未订阅的事件,您将从哪里获取这些事件?
我认为此时不使用事件源的系统有很大的不同。如果您必须在系统 A 中实现一个依赖于数据的功能,该功能在 A 中不可用,但在另一个系统 B 中可用,并且您通过 NHibernate 等 ORM 工具持久保留当前状态,您可以简单地将数据从 A 导入到 B由于使用事件源的系统依赖于事件来达到当前状态,因此您必须导入过去错过但现在需要的所有事件。
对我来说,有几种不同的方法可以解决这个问题。
- 每个系统都会保存所有发布的事件。这使您能够根据需要重新发布事件或将它们导入到另一个系统中。
- 每个系统都会保存发生的所有事件,甚至是那些(尚)不需要处理的事件。
- 来自所有系统的所有事件都存储在中央事件日志中。如果您需要处理过去发生但您未订阅的事件,您可以从此处导入它。
你如何处理这种情况?您在哪里保存事件?
编辑
感谢 Roy Dictus 的回答。我仍然不确定如何处理以下情况:
该网站发布了事件 CustomerRegistered、CustomerPurchasedProduct 和 CustomerMarkedProductAsFavorite。 在当前版本的后端中,必须显示客户以及他们的购买情况。客户标记为最喜欢的内容对该版本的系统不感兴趣。因此后端仅订阅了 CustomerRegistered 和 CustomerPurchasedProduct。
现在营销部门还希望将喜爱的产品的信息显示在客户详细信息页面上。由于后端未订阅 CustomerMarkedProductAsFavorite,因此该信息在后端不可用。我从哪里获取这些信息?
Given you have multiple systems, which are integrated by events, and all of them are using event sourcing. Where do you store the events?
In my case I have three systems:
- A website, which is a shop
- A backend for the Website to manage customers, products etc.
- An accounting system
Whenever a domain event happens in one of those systems the event is published and can be processed by the other systems. All systems are using event sourcing.
I am wondering where you would save the events. Of course each system has to store all events that it processed because it is using event sourcing and therefore depends on the events it once processed.
But what about the other events that where not needed and therefore the system did not subscribe to? I am struggling with the fact that requirements can change, such that a system would have to process events from the past that it did not persist. Where would you get these events from, if the system needed to process events that it did not subscribe when they occured?
I think there is a big difference to systems that do not use event sourcing at this point. If you have to implement a feature in a system A which depends on data, that is not available in A, but in another system B, and you persistent current state via a ORM tool like NHibernate you can simply import that data from A to B. Since a system, that uses event sourcing, depends on events to get to it's current state you have to import all the events that you missed in the past but are need now.
For me there are a few different approaches to this problem.
- Each system saves all events that is publishes. This gives you the ability to republish the events if needed or to import them into another system.
- Each system saves all events that happen, even those which do not need to be processed (yet).
- All events from all system are stored in central event log. If you need to proccess a event that happened in the past but you did not subscribe to you can import it from here.
How do you handle such a situation? Where do you save your events?
Edit
Thanks Roy Dictus for your answer. I'm still not sure how to handle the following situation:
The website publishes the events CustomerRegistered, CustomerPurchasedProduct and CustomerMarkedProductAsFavorite.
In the current version of the backend customers haave to be displayed and their purchases have to be displayed. What a customer marked as a favorite is not of interest in that version of the system. Thus the backend only subscribed to CustomerRegistered and CustomerPurchasedProduct.
Now the marketing department also wants the information about the favorite products to be shown on the customer details page. Since the backend didn't subscribe to CustomerMarkedProductAsFavorite this information is not available in the backend. Where do I get that information from?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编辑以适应您的额外问题:
如果另一个应用程序突然对额外信息感兴趣,它必须向它现在感兴趣的事件添加侦听器。
此外,这些事件的所有源都可以重播这些事件。重播是事件驱动系统的一个强大功能,可以实现此类场景。因此,事件源仅重播选定的事件(例如,过去 6 个月的所有 CustomerMarkedItemAsFavorite 事件)。已经消耗了这些事件的系统应该认识到重放的事件是“旧”事件(即它已经处理过的事件)并忽略它们。
这样,任何更新为使用来自其他子系统的额外信息的子系统都可以获取该信息并在单个批处理操作中获得所有最新信息。
EDIT to accommodate your extra question:
If another application suddenly becomes interested in extra information, it has to add listeners to the events it is now interested in.
Furthermore, all sources of these events can then replay those events. Replay is a powerful feature of event-driven systems that allows for such scenarios. So, the event sources replay only the selected events (say, all CustomerMarkedItemAsFavorite events of the last 6 months). Systems that have already consumed these events should recognize that the events replayed are "old" ones (i.e., ones that it has already processed) and ignore them.
This way, any subsystem that is updated to use extra information from the other subsystems can get that information and get all up-to-date in a single batch operation.
WRT 您的编辑:是否确实需要访问历史 CustomerMarkedProductAsFavorite 数据。更改后端以订阅新数据,然后就可以继续使用了。如果您确实需要,可以将如何回填丢失的数据作为一个单独的问题来解决。
Roy 已经概述了一种可能的架构,该架构将确保您拥有客户标记的产品作为最喜欢的数据以供将来回填。
WRT your edit: Is it really a requirement to also access the historical CustomerMarkedProductAsFavorite data. Change the backend to subscribe to the new data and then you have it going forward. You can work out how to backfill the missing data as a separate issue if you really need it.
Roy has already outlined one possible architecture that would ensure you have theCustomerMarkedProductAsFavorite data to backfill in future.