事件驱动的架构和事件结构 [英] Event-driven architecture and structure of events
问题描述
我是EDA的新手,我已经学到了很多好处,并且可能有兴趣在下一个项目中应用它,但是仍然不了解.
引发事件时,哪种模式最合适:
- 将事件命名为"CustomerUpdate",并包含有关客户的所有信息(是否更新)
- 将事件命名为"CustomerUpdate",并且仅包含真正更新过的信息
- 将事件命名为"CustomerUpdate",并包含最低限度的信息(标识符)和/或URI,以使消费者检索有关此客户的信息.
我问这个问题,因为我们的一些事件可能很繁琐,也很频繁.
感谢您的回答和时间.
将事件命名为"CustomerUpdate"
首先让我们从您的事件名称开始.事件的目的是描述已经发生的事情.这与命令不同,后者发出尚未发生的事情的指令.
您的事件名称"CustomerUpdate"在这方面听起来模棱两可,因为它可能描述的是过去的事情或将来的事情.
CustomerUpdated 会更好,但是即使这样, Updated 还是另一个模棱两可的术语,并且在业务环境中不是特定的.为什么在这种情况下更新了客户?是因为他们更改了付款明细吗?搬家了吗他们从银级升为金级了吗?可以根据需要进行特定的事件.
乍一看,这似乎有点过分考虑,但是当您从事件有效负载中删除数据和上下文时,事件命名就变得尤为重要,而更倾向于 skinny 事件(问题中的选项3" ,我将在下面讨论).
这并不意味着总是建议在这种粒度级别上定义事件,仅是它是一条在项目早期向您开放的途径,可能会在以后派发红利(或可能使您陷入困境)数千种事件类型.
回到您的实际问题,让我们依次选择每个选项:
将事件命名为"CustomerUpdate",并包含所有信息(已更新 关于客户)
我们将此称为胖"消息的样式".
胖消息(也称为快照)表示所描述实体在给定时间点的状态,其中所有事件上下文都存在于有效负载中.它们很有趣,因为消息本身代表了服务和消费者之间的契约.它们可用于在业务域之间传递状态变化,在这种情况下,最好由消费者在消息处理期间显示所有事件上下文.优势:
- 自我一致性-完全可以在不了解其他系统的情况下使用.
- 易于消费(upsert).
缺点:
- 脆弱-服务与消费者之间的契约与消息本身相关.
- 如果消息以错误的顺序到达,则很容易用旧数据覆盖当前数据(提示:您可以使用
我们将此模式称为 Delta 消息.
增量通常在很多方面都类似于胖消息,尽管它们的生成和使用通常更为复杂.一个很好的例子是 JSONPatch 标准.
因为它们只是事件实体的部分描述,所以增量还附带了一个内置的假设",使消费者对所描述的事件有所了解.因此,它们可能不太适合在事件实体可能不为人所知的业务域外发送.
当在共享相同实体模型的系统之间同步数据时,增量确实闪闪发亮,理想情况下,将其持久存储在非关系存储中(例如,no-sql).在这种情况下,可以检索实体,应用增量,然后以最小的努力再次持久化.
优势:
- 比胖消息更小
- 在涉及共享实体模型的用例中表现出色
缺点:
- 易碎-与Fat消息类似,合同已嵌入到消息中.
- 易于用旧数据覆盖当前数据.
- 生成和使用的复杂
将事件命名为"CustomerUpdate",并包含最少的信息 (标识符)和/或URI,以使消费者检索信息 关于此客户.
我们称其为 Skinny 消息.
瘦消息与您定义的其他消息模式不同,因为消息中的服务/消费者合同不再是显式的,但暗含着在以后的某个时间,消费者将检索事件上下文.这使合同和消息交换脱钩,这是一件好事.
这可能会或可能不会很好地适合跨业务域的事件通信,具体取决于您的企业的设置方式.因为事件有效负载很小(通常只是一个ID),所以除了事件的名称外,没有其他上下文,消费者可以根据该上下文进行处理决策.因此,确保适当命名事件变得更加重要,尤其是当消费者可以通过多种方式响应 CustomerUpdated 消息时.
此外,在事件数据中包含实际资源地址可能不是一个好习惯-因为事件是已经发生的事情,事件消息通常是不可变的,因此,如果事件发生,则事件中的任何信息都应永远为真需要重播.在这种情况下,资源地址很容易过时,事件将无法重播.
优势:
- 使服务合同与消息脱钩.
- 事件名称中包含的有关事件的信息.
- 自然幂等(带有时间戳).
- 通常很小.
- 易于生成和使用.
缺点:
- 消费者必须进行额外的调用才能检索事件上下文-需要其他系统的明确知识.
- 在用户检索事件上下文时,事件上下文可能已过时,因此这种方法通常不适用于某些实时应用程序.
发起活动时,哪种模式最合适?
我认为对此的答案是:它取决于很多事情,并且可能没有一个正确的答案.
评论更新:也很值得一读,关于消息的非常古老的经典博客文章: http://vanguardea.com/killing-the-command-message-should-we-use-events-or-documents/)
I'm new to EDA and I've read a lot about benefits and would probably be interested to apply it during my next project but still haven't understood something.
When raising an event, which pattern is the most suited:
- Name the event "CustomerUpdate" and include all information (updated or not) about the customer
- Name the event "CustomerUpdate" and include only information that have really been updated
- Name the event "CustomerUpdate" and include minimum information (Identifier) and/or a URI to let the consumer retrieves information about this Customer.
I ask the question because some of our events could be heavy and frequent.
Thx for your answers and time.
解决方案Name the event "CustomerUpdate"
First let's start with your event name. The purpose of an event is to describe something which has already happenned. This is different from a command, which is to issue an instruction for something yet to happen.
Your event name "CustomerUpdate" sounds ambiguous in this respect, as it could be describing something in the past or something in the future.
CustomerUpdated would be better, but even then, Updated is another ambiguous term, and is nonspecific in a business context. Why was the customer updated in this instance? Was it because they changed their payment details? Moved home? Were they upgraded from silver to gold status? Events can be made as specific as needed.
This may seem at first to be overthinking, but event naming becomes especially relevant as you remove data and context from the event payload, moving more toward skinny events (the "option 3" from your question, which I discuss below).
That is not to suggest that it is always appropriate to define events at this level of granularity, only that it is an avenue which is open to you early on in the project which may pay dividends later on (or may swamp you with thousands of event types).
Going back to your actual question, let's take each of your options in turn:
Name the event "CustomerUpdate" and include all information (updated or not) about the customer
Let's call this "pattern" the Fat message.
Fat messages (also called snapshots) represent the state of the described entity at a given point in time with all the event context present in the payload. They are interesting because the message itself represents the contract between service and consumer. They can be used for communicating changes of state between business domains, where it may be preferred that all event context be present during message processing by the consumer.
Advantages:
- Self consistent - can be consumed entirely without knowledge of other systems.
- Simple to consume (upsert).
Disadvantages:
- Brittle - the contract between service and consumer is coupled to the message itself.
- Easy to overwrite current data with old data if messages arrive in the wrong order (hint: you can mitigate this by using the event sourcing pattern)
- Large.
Name the event "CustomerUpdate" and include only information that have really been updated
Let's call this pattern the Delta message.
Deltas are similar to fat messages in many ways, though they are generally more complex to generate and consume. A good example here is the JSONPatch standard.
Because they are only a partial description of the event entity, deltas also come with a built-in "assumption" that the consumer knows something about the event being described. For this reason they may be less suitable for sending outside a business domain, where the event entity may not be well known.
Deltas really shine when synchronising data between systems sharing the same entity model, ideally persisted in non-relational storage (eg, no-sql). In this instance an entity can be retrieved, the delta applied, and then persisted again with minimal effort.
Advantages:
- Smaller than Fat messages
- Excels in use cases involving shared entity models
Disadvantages:
- Brittle - similar to the Fat message, the contract is embedded in the message.
- Easy to overwrite current data with old data.
- Complex to generate and consume
Name the event "CustomerUpdate" and include minimum information (Identifier) and/or a URI to let the consumer retrieves information about this Customer.
Let's call this the Skinny message.
Skinny messages are different from the other message patterns you have defined, in that the service/consumer contract is no longer explicit in the message, but implied in that at some later time the consumer will retrieve the event context. This decouples the contract and the message exchange, which is a good thing.
This may or may not lend itself well to cross-business domain communication of events, depending on how your enterprise is set up. Because the event payload is so small (usually just an ID), there is no context other than the name of the event on which the consumer can base processing decisions; therefore it becomes more important to make sure the event is named appropriately, especially if there are multiple ways a consumer could respond to a CustomerUpdated message.
Additionally it may not be good practice to include an actual resource address in the event data - because events are things which have already happened, event messages are generally immutable and therefore any information in the event should be true forever in case the events need to be replayed. In this instance a resource address could easily become obsolete and events would not be re-playable.
Advantages:
- Decouples service contract from message.
- Information about the event contained in the event name.
- Naturally idempotent (with time-stamp).
- Generally tiny.
- Simple to generate and consume.
Disadvantages:
- Consumer must make additional call to retrieve event context - requires explicit knowledge of other systems.
- Event context may have become obsolete at the point where the consumer retrieves it, making this approach generally unsuitable for some real-time applications.
When raising an event, which pattern is the most suited?
I think the answer to this is: it depends on lots of things, and there is probably no one right answer.
Update from comments: Also worth reading, a very old, classic, blog post on messaging: https://docs.microsoft.com/en-gb/archive/blogs/nickmalik/killing-the-command-message-should-we-use-events-or-documents (also here: http://vanguardea.com/killing-the-command-message-should-we-use-events-or-documents/)
这篇关于事件驱动的架构和事件结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!