Event-driven Architecture – Everything You Need to Know
event-driven architecture is
a common pattern found alongside microservices and other decoupled services
or apps. In an event-driven architecture, each service in an ecosystem reacts and takes
action upon an event it receives. There are both upsides and downsides to event-driven
architecture but before we get into that, let’s look at an example of how event-driven
architecture works so you know exactly what it is. Let’s say we have a standard e-commerce
system that allows users to purchase a product on a website. when a purchase is
completed, several things need to happen. 1. an email receipt should
be sent to the purchaser 2. Inventory numbers should be
updated to reflect that there are now fewer of the products available for purchase
3. a fulfillment system needs to be notified so the purchased product can be shipped
4. a purchase history should be updated for both the customer and the
company to use for later reference So it looks like we need to have five
services to make all of this work.
1. the e-commerce system
itself for taking the money 2. a service that sends emails
3. an inventory control service 4. a fulfillment service
5. an order history service in a more traditional service-to-service
direct communication architecture, the e-commerce service would complete the
purchase with the customer then several point-to-point calls would be made. it
would call each of the other four services, likely using a REST API, to tell those
services to complete their actions.
Now, in an event-driven architecture, we would
eliminate that point-to-point relationship between all of these services. instead, we’ll
introduce another service which we’ll refer to as an “event router”. This event router can
receive events from event publishers and it will push events to event subscribers. now There
are many different brands of event routers out there and I’ll talk about that in just a bit
but for now, let’s keep going with the example. so let’s rearrange the diagram. in this new
event-driven setup, the ecommerce system becomes the event publisher and the other
four systems become the event subscribers. in this setup, the e-commerce
platform no longer needs to make several outbound calls to each
service with instructions on what to do. instead, after the purchase is completed, it
sends an event to the event router. this event indicates that a purchase has been completed
as well as any other necessary details about the completed purchase that are necessary to
allow the other services to complete their task.
After the event router receives the event,
it then pushes the event details to the event subscribers or the subscribers
pull the events from the router (both options are usually available). When each
of the four subscribers receives the events, they complete their necessary tasks and then
acknowledge to the router that they’re done. At this point, the same outcome has
been completed between these two different setups, but in slightly different ways. so, now that you know what
event-driven architecture is, let’s discuss why you would
want to do this. After all, it kind of looks like I added more complexity here
because I added a sixth service to the stack. and you’re right. I did add another service
here but following this pattern has some huge upsides compared to the point-to-point method.
I think the first thing we should discuss is how event routers and queuing services greatly
reduce the possibility of system failures.
In the example above I kind of breezed through the
part where the event subscribers acknowledged that they had completed their tasks.
this feature is a key trait of an event-driven architecture. you see, when the router
receives an event, it knows which subscribers should receive that event and that they must acknowledge they have completed their task. when the router attempts to send the event
to the subscriber, if the subscriber doesn’t reply and says “All set here”, the router will retry
sending that event until it has been acknowledged. This means that one of your subscribers could
be completely down for even an extended amount of time and still receive all of its events
when it comes back up, ensuring consistency between your systems. most event routers even
have the capability of reporting when an event fails too many times and it gives up on sending
an event. not ideal, but this does allow for engineers to fix the issue and also allows for
manual remediation of the event that failed.
Note that not all routers support subscribers and queuing of tasks
as one service. I’ll cover that later. in the point-to-point approach, the
commerce system would have to know how to handle failures and attempt to retry the
API calls until it succeeded. if this is an extended amount of time, this could cause
the e-commerce system to slow down or crash as it attempts to remember and retry all
of these requests until they are complete. this can cause slowdowns for the end
user or even a complete service failure.
The second major advantage of an event-driven
architecture is related to maintaining a decoupled relationship of microservices or separation
of duties. Let’s start on the publisher’s end. in our example, the e-commerce system’s
responsibility in this process is greatly simplified. all the e-commerce system needs
to do here is publish a single event to the event router. it no longer needs to
be concerned about what happens next. because of this, we can now easily add
additional subscribers to this process with zero changes to the e-commerce system.
Let’s say we wanted to create a service that alerts the store owner of a purchase via Slack.
well, that’s no big deal now. Just add Slack as a subscriber to the event router and it will
also start to receive events about new orders. on the flip side of that, what if we wanted
to completely replace our e-commerce system with something new? Well, as long as that new
system can publish events about new purchases, zero changes need to be made to the subscribers.
So those are the plusses to
event-driven architecture, but there can also be some downsides. the biggest downside to event-driven
architecture is that everything is real-time. while that can be also a plus,
I’ll explain where it causes a problem. let’s say that you want to introduce a system that
maintains user profiles of your customers. you add this new service as a subscriber to
your router and now each new purchase shows up on the user’s profile.
Well, that’s great but
what about the purchases they made last year? in this scenario, you would need to
do some additional work before you could just set it and forget
it. You would likely need to batch-load all of the previous order history
into the new system and then add it to the router so it can get all new orders. as you can see,
it can take some planning to ensure you get everything in sync, but moving forward you will
enjoy the benefits of the event-driven system.
So I promised earlier that I would cover the
brands of event routers out there. As usual, all of the major cloud hosting companies
have their own flavors of event routers. AWS has SQS and SNS. I’ll put a link
in the description so you can see the differences. it’s mainly a
difference between persistence and guaranteed deliverability. Oftentimes
you may end up using both. GCP has pubsub which is my personal favorite. It’s kind of a combination of both AWS services and it allows for multiple subscribers with guaranteed deliverability in both a push and pull setup. beyond the cloud providers, there are also open-source event routers out
there. a couple of these are Apache Kafka which is highly configurable and can
do lots of fun stuff when configured correctly and Rabbitmq which I honestly have never used but I didn’t want to leave it out because it’s
a very well-known product in this space.
so there you have it. That’s everything
you need to know to get started with an event-driven architecture. if
you liked this video leave me a like and if you have questions or
comments please leave them below. until next time, happy coding!