The CTO of a company I have worked for used to say that services should be loosely coupled but tightly integrated. I didn’t realize until a lot later how true that statement is as you’re building out microservices. How those microservices communicate with each other has also changed quite a bit. More often than not, they send messages using asynchronous protocols. As an industry, we decided that this new way of building apps should be called “Event-Driven Architecture (EDA).”
What is Event-Driven anyway?
Thinking about event-driven architecture starts with thinking about events. In this context, events are the facts tell what has happened in your app. You fire it off and forget about it, letting someone else decide what to do with it. A large part of our daily lives is event-driven. That “like” you got on your tweet, the text message on your phone, or the email that your GitHub keys were stolen are all events.
Event-driven means that all the other parts of your app react to those events. It’s like a jazz band, where the players react to the melody played by the others. As the drums begin to play, the trumpets react. To have your microservices act like jazz musicians too, you’ll need two things. You’ll need APIs and events to communicate, and your microservices should be stateless.
Why do I need APIs?
Greg Young said: “When you start modeling events, it forces you to think about the behavior of the system.” Those events represent what your microservice sends out into the world for others to react on and what your microservice will respond to. In the REST world, developers create API specifications as a description of the interface between microservices. In an event-driven world, you can still use HTTP but there are better options. In an event-driven world, you use brokers.
What are event brokers?
Let’s use a definition from Gartner for what an event broker is: “middleware products that are used to facilitate, mediate and enrich the interactions of sources and handlers in event-driven computing.” Today, there are many different brokers out there that you can use. Some common examples are Apache Kafka, RabbitMQ, and Solace’s Event Broker. With these tools, developers can still create API specifications using a new project called AsyncAPI. Their tools help developers create API specifications, and generate code from them, for event-driven apps.
from: https://martin.kleppmann.com/2015/05/27/logs-for-data-infrastructure.html
As we break down our large monolithic app into microservices and want them to send out events, we can’t rely on just HTTP as the way for services to communicate. As you build more services that are interested in the same event, you don’t want to update the producer of the events. Event brokers make the event available to another subscriber, without making changes to the code. The same holds true for “scaling out”. As some microservices get very busy, you want to scale the number of instances of that service and not change the event publisher to be able to send events to that new instance. Event brokers that care of that too. A third reason why event brokers are great for event driven architectures is that those brokers keep track of the events that are sent. If your microservice isn’t running for some reason and starts again, the events it missed are waiting to be processed.
Where does my state go?
The jazz band doesn’t keep all their music in their head, so your microservices shouldn’t either. Your services can be deployed to a Kubernetes cluster, Virtual Machines, or serverless platforms. For event-driven architectures, it doesn’t really matter where you run your code. What matters is that your microservices don’t keep track of state themselves, they rely on external systems like databases or message brokers to keep track of it.
If the music your band plays has more to do for trumpets than a single player can handle, you need to add another player. Just like scaling up the number of trumpet players, you want to scale up the instances of your microservices when your app gets busy. If all instances of a microservice keep track of their own state, you have to synchronize between them and make sure all those instances operate on the same state. Brokers like Apache Kafka offer the solution by keeping track of state for your services, regardless of which programming language or platform you deploy them to. Adding or removing microservices is now a piece of cake.
When you let the broker keep track of the events, and of the state, you can look at a pattern called “event sourcing”. That means that instead of only keeping track of the current state of a microservice, you also keep track of every new event to generate a log of everything that has happened. Microservices following that pattern have a bunch of awesome benefits. Those microservices can receive events if they weren’t ready to handle them, replay events after fixes have been deployed, roll back changes if something goes wrong down the line, or even rebuild the entire state of an app. Apache Kafka became famous for supporting this particular pattern.
An event-driven architecture lets you speed up development and gives you faster and more frequent deployments regardless of where you deploy your services.
Continuously verifying event-driven architectures
As a team, we’ve talked about Continuous Verification quite a bit. I strongly believe that event-driven architectures are a great fit for Continuous Verification. You want to be thoughtful about what you’re spending because event-driven architectures give you the ability to scale to easily infinity and back. As you’re keeping your audit log, your state, in a separate place, you need security policies and make sure that the events can be trusted. On top of that, you need to think about observability and how some of these features will make your life easier.
What’s next?
The next time you’re listening to a jazz band play, think about how they act and react to each other and how that is similar to your application architecture. Over the coming period, we’ll share more on how we’ve built our ACME Fitness App to be event-driven and which tools we’ve used. In the meanwhile, let me know your thoughts and send me or the team a note on Twitter.