Event-driven architectures (original) (raw)

An event-driven architecture is a software design pattern in which microservices react to changes in state, called events. Events can either carry a state (such as the price of an item or a delivery address) or events can be identifiers (a notification that an order was received or shipped, for example). The events trigger microservices that work together to achieve a common goal, but don't have to know anything about each other except the event format. Although operating together, each microservice can apply a different business logic, and emit its own output events.

An event has the following characteristics:

In an event-driven system, events are generated by event producers, ingested and filtered by an event router (or broker), and then fanned out to the appropriate event consumers (or sinks). The events are forwarded to the consumers based on subscriptions defined by one or more matching enrollments(when using Eventarc Advanced) or one or more matching triggers (when usingEventarc Standard). These three components—event producers, event router, event consumers—are decoupled and can be independently deployed, updated, and scaled:

Event brokers and subscribers

The event router links the different services and is the medium through which messages are sent and received. It executes a response to the original event generated by an event producer and sends this response downstream to the appropriate consumers. Events are handled asynchronously and their outcomes are decided when a service reacts to an event or is impacted by it, as in the following diagram of a very simplified event flow:

Event-driven architecture

When to use event-driven architectures

Consider the following usages when designing your system.

Benefits of event-driven architectures

These are some of the advantages when building an event-driven architecture.

Loose coupling and improved developer agility

Event producers are logically separated from event consumers. This decoupling between the production and consumption of events means that services are interoperable but can be scaled, updated, and deployed independently of each other.

Loose coupling reduces dependencies and lets you implement services in different languages and frameworks. You can add or remove event producers and receivers without having to change the logic in any one service. You don't need to write custom code to poll, filter, and route events.

Asynchronous eventing and resiliency

In an event-driven system, events are generated asynchronously, and can be issued as they happen without waiting for a response. Loosely coupled components means that if one service fails, the others are unaffected. If necessary, you can log events so that the receiving service can resume from the point of failure, or replay past events.

Push-based messaging, real-time event streams, and lower costs

Event-driven systems allow for push-based messaging and clients can receive updates without needing to continuously poll remote services for state changes. These pushed messages can be used for on-the-fly data processing and transformation, and real-time analysis. Moreover, with less polling, there is a reduction in network I/O, and decreased costs.

Simplified auditing and event sourcing

The centralized location of the event router simplifies auditing, and lets you control who can interact with a router, and which users and resources have access to your data. You can also encrypt your data both in transit and at rest.

Additionally, you can make use of event sourcing, an architectural pattern that records all changes made to an application's state, in the same sequence that they were originally applied. Event sourcing provides a log of immutable events which can be kept for auditing purposes, to recreate historic states, or as a canonical narrative to explain a business-driven decision.

Architectural considerations

An event-driven architecture might require that you approach your application design in a new way. Although well suited for applications that make use of microservices or decoupled components, you should also consider the following:

What's next