TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

The Dual Nature of Events in Event-Driven Architecture

112 点作者 lutzh7 个月前

11 条评论

bob10297 个月前
The triggering of the action is a direct consequence of the information an event contains. Whether or not an action is triggered should not be the responsibility of the event.<p>If you are writing events with the intention of having them invoke some specific actions, then you should prefer to invoke those things directly. You should be describing a space of things that have occurred, not commands to be carried out.<p>By default I would only include business keys in my event data. This gets you out of traffic on having to make the event serve as an aggregate view for many consumers. If you provide the keys of the affected items, each consumer can perform their own targeted lookups as needed. Making assumptions about what views each will need is where things get super nasty in my experience (i.e. modifying events every time you add consumers).
评论 #42019072 未加载
评论 #42019046 未加载
评论 #42018617 未加载
评论 #42026281 未加载
评论 #42020185 未加载
dkarl7 个月前
Events are published observations of facts. If you want to be able to use them as triggers, or to build state, then you have to choose the events and design the system to make that possible, but you always have to ensure that systems only publish facts that they have observed.<p>Most issues I&#x27;ve seen with events are caused by giving events imprecise names, names that mean more or less than what the events attest to.<p>For example, a UI should not emit a SetCreditLimitToAGazillion event because of a user interaction. Downstream programmers are likely to get confused and think that the state of the user&#x27;s credit limit has been set to a gazillion, or needs to be set to a gazillion. Instead, the event should be UserRequestedCreditLimitSetToAGazillion. That accurately describes what the UI observed and is attesting to, and it is more likely to be interpreted correctly by downstream systems.<p>In the article&#x27;s example, SeatSelected sound ambiguous to me. Does it only mean the user saw that the seat was available and attempted to reserve it? Or does it mean that the system has successfully reserved the seat for that passenger? Is the update finalized, or is the user partway through a multistep process that they might cancel before confirming? Depending on the answer, we might need to release the user&#x27;s prior seat for other passengers, or we might need to reserve both seats for a few minutes, pending a confirmation of the change or a timeout of their hold on the new seat. The state of the reservation may or may not need to be updated. (There&#x27;s nothing wrong with using a name like that in a toy example like the article does, but I want to make the point that event names in real systems need to be much more precise.)<p>Naming events accurately is the best protection against a downstream programmer misinterpreting them. But you still need to design the system and the events to make sure they can be used as intended, both for triggering behavior and for reporting the state and history of the system. You don&#x27;t get anything automatically. You can&#x27;t design a set of events for triggering behavior and expect that you&#x27;ll be able to tell the state of the system from them, or vice-versa.
评论 #42021585 未加载
评论 #42027830 未加载
exabrial7 个月前
Well put!<p>We do a lot of event driven architecture with ActiveMQ. We try to stick messaging-as-signalling rather than messaing-as-data-transfer. These are the terms we came up with, I&#x27;m sure Martin Fowler or someone else has described it better!<p>So we have SystemA that is completing some processing of something. It&#x27;s going to toss a message onto a queue that SystemB is listening on. We use an XA to make sure the database and broker commit together<i>1. SystemB then receives the event from the queue and can begin it&#x27;s little tiny bit of business processing.<p>If one divides their &quot;things&quot; up into logical business units of &quot;things that must all happen, or none happen&quot; you end up with a pretty minimalistic architecture thats easy to understand but also offers retry capabilities if a particular system errors out on a single message.<p>It also allows you to take SystemB offline and let it&#x27;s work pile up, then resume it later. Or you can kick of arbitrary events to test parts of the system.<p></i>1: although if this didn&#x27;t happen, say during a database failure at just the right time, the right usage of row locking, transactions, and indexes on the database prevent duplicates. This is so rare in practice but we protect against it anyway.
评论 #42022430 未加载
评论 #42026768 未加载
svilen_dobrev7 个月前
like, events vs documents, ~2007:<p><a href="https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-gb&#x2F;archive&#x2F;blogs&#x2F;nickmalik&#x2F;killing-the-command-message-should-we-use-events-or-documents" rel="nofollow">https:&#x2F;&#x2F;learn.microsoft.com&#x2F;en-gb&#x2F;archive&#x2F;blogs&#x2F;nickmalik&#x2F;ki...</a>
评论 #42019128 未加载
deterministic7 个月前
I design events following these rules:<p>1. You should be able to recreate the complete business state from the complete event sequence only. No reaching out to other servers&#x2F;servies&#x2F;DB’s to get data.<p>2. The events should be as small as possible. So only carry the minimum data needed to implement rule #1<p>That’s it. It works really well in practice.
hcarvalhoalves7 个月前
The &quot;produce a trigger event then have the consumer reach back to the producer and fetch data&quot; can be an anti-pattern. You expose yourself to all kinds of race conditions and cache incoherency, then you start trying to fix with cache invalidation or pinning readers, and the result is you can&#x27;t scale readers well.<p>If you&#x27;re a using a message queue, the message should convey necessary information such that, if all messages were replayed, the consumer would reach the same state. Anything other than that, you&#x27;ll be in a world of pain at scale.
评论 #42027233 未加载
kaba07 个月前
I am going on a bit of a tangent here, but I always wondered, are those of you who use absolutely huge event-driven architectures, have you ever got yourself into a loop? I can&#x27;t help but worry about such, as event systems are fundamentally Turing-complete, and with a complex enough system it doesn&#x27;t seem too hard to accidentally send an event because A, which will eventually, multiple other events later again cases A.<p>Is it a common occurence&#x27; and if it happens is it hard to debug&#x2F;fix? Does Kafka and other popular event systems have something to defend against it?
评论 #42022996 未加载
评论 #42025883 未加载
评论 #42021540 未加载
评论 #42027454 未加载
revskill7 个月前
Event is a point in time. State is a range in time.<p>Geometrically speaking.<p>So, what should be in an event ? To me, it&#x27;s the minimum but sufficient data on its own to be understandable.
lutzh7 个月前
Article observing that events in event-driven architecture are both triggers of actions and carriers of data, and that these roles may conflict in the event design. Submitted by author.
评论 #42021191 未加载
cushpush7 个月前
I don&#x27;t understand where this distinction is useful - signals are data, just a tiny bit, and data is a signal, just a lot of it. Are you talking about transmission-size? Or are we resigned to the fact that intra-computer communication is inefficient and it&#x27;s enough to postulate about the sizes of bandages?
stevenalowe7 个月前
Thank you for this well-written, well-reasoned, and thoroughly enjoyable article!<p>Yet I am troubled by it, and must disagree with some of the premises and conclusions. Only you know your specific constraints, so my &#x27;armchair architecting&#x27; may be way off target. If so, I apologize, but I was particularly disturbed by this statement:<p>&quot;events that travel between services have a dual role: They trigger actions and carry data.&quot;<p>Yes, sort of, but mostly no. Events do not &quot;trigger&quot; anything. The recipient of an event may perform an action in response to the event, but events cannot know how they will be used or by whom. Every message carries data, but a domain event is specifically constrained to be an immutable record of the fact that something of interest in the domain has happened.<p>The notion of modeling &#x27;wide&#x27; vs &#x27;short&#x27; events seems to ignore the domain while conflating very different kinds of messages - data&#x2F;documents&#x2F;blobs, implementation-level&#x2F;internal events, domain events, and commands.<p>Modeling decisions should be based on the domain, not wide vs short. Domain events should have names that are meaningful in the problem domain, and they should not contain extraneous data nor references to implementation details&#x2F;concepts. This leads to a few suggestions:<p>* Avoid Create&#x2F;Read&#x2F;Update&#x2F;Delete (CRUD) event names as these are generic implementation-level events, not domain events. Emit such events &quot;under the hood&quot; for replication&#x2F;notification if you must, but keep them out of the domain model.<p>* Name the domain event specifically; CRUD events are generally undesirable because they (a) are an implementation detail and (b) are not specific enough to understand without more information. Beware letting an implementation decision or limitation corrupt the domain model. In this example, the BookingUpdated event adds no value&#x2F;information, makes filtering for the specific event types more complex, and pollutes the domain language with an unnecessary and potentially fragile implementation detail (the name of the db table Booking, which could just as easily have been Reservation or Order etc). SeatSelected is a great domain event name for a booking&#x2F;reservations system. BookingSeatSelected if there is further scope beyond Booking that might have similar event names. BookingUpdated is an implementation-level, internal event, not part of the problem domain.<p>* What data is necessary to accurately record this domain event? A certain minimal set of relevant data items will be required to capture the event in context. Trying to anticipate and shortcut the needs of other&#x2F;future services by adding extraneous data is risky. Including a full snapshot of the object even more risky, as this makes all consumers dependent on the entire object schema.<p>* The notion of &quot;table-stream duality&quot; as presented is likewise troublesome, as that is an implementation design choice, not part of the domain model. I don&#x27;t think that it is a goal worthy of breaking your domain model, and suggest that it should not be considered at all in the domain model&#x27;s design. Doing so is a form of premature optimization :)<p>* That said, separating entity and event streams would keep table-stream duality but require more small tables, i.e. one domain event type per stream and another Booking stream to hold entity state as necessary. A Booking service can subscribe to SeatSelected et al events (presumably from the UI&#x27;s back-end service) and maintain a separate table for booking-object versions&#x2F;state. A SeatReserved event can be emitted by the Booking service, and no one has to know about the BookingUpdated event but replication hosts.<p>Thanks again for writing and posting this, it really made me think. Good luck with your project!
评论 #42032178 未加载