33. Event-Driven Architecture (Part 1)
Chris Hickman and Jon Christensen of Kelsus and Rich Staats from Secret Stache begin a micro series focusing on the how and why of event-driven architecture and publish-subscribe design pattern.
Some of the highlights of the show include:
- Event-driven Architecture: Define what actions can occur in a system and notifications that are generated when they happen
- Other components can subscribe to those messages to be able to perform other actions; creates loose coupling pattern with no dependencies
- Event-driven architecture is applicable to most scenarios – anywhere and everywhere
- Loose coupling is a fundamental piece to building software and systems; components are independent of other components – don’t have to make corresponding changes
- As you scale and have more dependent services or additional functionality, you can scale up appropriately at the component level and as you need to
- Tackling who’s calling who when it comes to API calls can be challenging, complex, and involve coupling; event-driven architecture with a straight line vs. a spiderweb
Links and Resources
Rich: In episode 33 of Mobycast, we begin a new micro-series on Event-Driven Architecture. In particular, we discuss the how and the why as well as the Pub/Sub design pattern. Welcome to Mobycast, a weekly conversation about containerization, Docker and modern software deployment. Let’s jump right in.
Jon: Good morning Rich and Chris, how are you doing today Rich?
Rich: I’m doing good, how are you?
Jon: Good, I’m excited for another episode of Mobycast. How about you Chris, how are you?
Chris: I’m doing great. Good to hear you guys.
Jon: Yeah. I don’t know if we’ve ever said that we’re pretty widely distributed. Rich being in Denver, me in the mountains of Colorado, and Chris in Seattle. Well, not in Seattle, but I mean, outer regions of the Seattle area.
What have you been up to this week, Chris?
Chris: After a pretty miserable September, otherwise, we’re now actually getting our Indian summer here in Seattle. I have been enjoying the sunshine, we’re getting up in 70 degrees temperatures, and getting out on my bicycle after work. Have been enjoying that. It’s very much a blessing here at the end of the cycling season for me.
Jon: Right, I like some warm, late fall temperatures and speaking of Indian summer, I was recently wondering if that term is still okay to say, it kind of isn’t. I just looked at, “What do you say now?” and the official term for weather forecasters is still Indian summer. There’s been some alternatives thrown out there but essentially, I was kind of surprised given how hard people are working to improve our language and the way we talk about people. That’s still very common among weather forecasters and everybody to say that. Rich, what have you been up to this week?
Rich: It’s not an Indian summer in Colorado right now. We finally got our first snow, but the day after it was 28 degrees, it was 60 degrees so, I played golf yesterday and Saturday. Interestingly enough, the summer’s over and I decided to start playing golf every day. I guess now, I’m just trying to make in as many rounds as I can or get in as many rounds as I can before the snow stays.
Jon: Cool, as for me, I’ve not been biking or doing anything recreational. We’ve got project starting at Kelsus and new people starting, and it’s a lot of work so, I’ve been doing that.
Today, we’re going to talk about something that, I don’t know, I just really like it because my very first job as a professional software developer, it was one of the first things that was introduced to me which is, Event-Driven Architectures or the Pub/Sub, publish-subscribe design pattern. That was a new concept to me, it’s not something that I learned in Computer Science in college and it was like, “Oh, this is how real software typically works within an enterprise.” So, we’re going to talk about it, how to do it with an AWS and how we do it at Kelsus for typically sized projects. We’re not talking about Facebook or Google scale, we’re talking about in the tens of thousands to hundreds of thousands of users type scale. Go ahead Chris, what is Event-Driven Architecture?
Chris: Event-Driven Architecture is definitely one of those key principles that are very useful when designing cloud or any kind of system architecture. Really what it is, it’s instead of thinking of your software as a sequential system where one step follows another one sequentially all inside the same component, with an Event-Driven design, you essentially define what interesting actions can occur in your system, when they do, you basically just send a message. Somehow, you signify like “Hey, this interesting thing happened.” and then that component just goes on its business, doing whatever it is that it’s doing. But by virtue of sending out that message, other components that may be interested in that can then subscribe to that and listen to that.
They can pick up their ears and listen for those events as they get emitted and when they do, they can then go perform additional whatever actions they want to do on that. It kind of almost like a “If this happened, then do this.” It’s very loosely coupled. One system doesn’t even have any idea that the other system exist. It becomes a very useful pattern, it’s very extensible.
We call it loosely coupled because again, this two systems, they know nothing at all to one another. One can be worked on independently than the other one and with no dependencies other than knowing, “What is that event–the name of the event,” or “How do I know what that event is so I can listen for it.” It’s a very useful pattern.
Jon: I like to think about one of my favorite examples of when this would be useful as an Order Management System. You might have a customer-facing website where people are ordering jeans. Usually, in good software design, you wouldn’t then have that same software be the software that somebody in warehouse was using to look at all the jeans orders and put them in boxes and send them out to people, there might be entirely different set of software that was for that part.
The ordering system or the customer-facing system would say “Hey, world, new jeans got ordered, new jeans got ordered.” and it’s constantly saying “We got another order. We got another order. We got another order.” and then somewhere else some other software that cares about orders is saying “Oh look, we got another order. Let’s do something about it. Let’s let some box packers know about it.” or whatever it is. That’s one of my favorite examples. Actually, that example itself makes me think of just front of house and back of house in a kitchen. It’s not quite the same but you know, you make a ticket then you put it on the thing and then the line cooks pick up the ticket and make the meal and put it on the counter. It’s kind of like that in my mind, that’s kind of what I think about.
Chris: It’s very applicable to just about any kind of scenario. It can be real world physical examples like you said just in a restaurant where, they can actually benefit from an Event-Driven system because right now, I think it’s probably more of like, we would call it a pulling system. Because those servers, they actually have to go back to the kitchen, “Is the order ready?” As opposed to just they’d be out in the restaurant somewhere and somehow they just know. It’s like, “Oh, it is ready. I can go back there and go pick it up.”
Jon: Okay, that’s it we’re stopping the episode…
Chris: Let’s just go back to 1985 and get everyone pagers and we’ll just send some messages through Twilio and call it good. These kinds of scenarios, just when you start thinking about it and look at it, they’re anywhere and everywhere. Not the whole ecommerce system they talk about too. It could be something like “Hey, whenever a package ships, let’s admit that event.” It may be that, there’s a customer account representative that their job is to follow-up with customers through satisfaction reasons or maybe you want to send out a survey to a select few so you can have some other component that’s listening to those package shipped orders and then deciding “who gets a survey and who doesn’t” type thing. Just very, very common.
Jon: We’ve talked about how this are loosely coupled. The software or the customers are going to browse products and make their order, it doesn’t know about the order fulfillment system, it has no idea it exists. Why are they loosely coupled? I sort of mentioned that’s just a good idea but just quickly, why is that a good idea.
Chris: I mean, loose coupling is just one of those kind of fundamental tenets of just building software or systems in general. The loose coupling again, it refers to the fact that components of the system are independent of the other, they don’t have hard dependencies. The reason why that’s good and useful is that it allows you to make changes to that without having to make corresponding changes and everything else it depends all on it.
Imagine you have one component that ends up providing services to three other components. If they are highly coupled, when you maybe change some implementation detail in the one component, that means that you now have to go change all three other components that leverage the services of that. Your complexity goes up and the ability to make changes and extend your components gets more difficult. The more components you have depending on that.
If you can change that instead to be more loosely coupled where it’s really at the service level, and you can confidently make changes in the one component and, not have to make changes to the other ones. It just makes life so easier, it’s so much more scalable, it’s extendable, and you’re not going to run into this decreasing velocity problem as you try to build and scale your system.
Jon: Right and yeah, that principle of loosely coupling things just applies really at every level in software from like you said the service level, it’s even higher, the business units, and the company might also benefit from being loosely coupled, then the software that they use is loosely coupled. Then inside the software, there’s maybe libraries that you’re using that are also loosely coupled to the software. Down into the computer itself, there’s different parts of a CPU that are hopefully a little bit loosely coupled from each other. Every layer, every level, we’re always looking to not couple things, if we can.
Chris: As you pointed out, it doesn’t have to be in just software. It can be in the physical world, and the way that businesses organize themselves. Amazon themselves, they do this. They’re two teams where they’re basically autonomous units that are chartered with some objective to go do and fill in. For the most part, those teams operate independently of the others type thing. Microsoft have the similar approach back in its early days. I think it’s grown so much now that it’s maybe less so, but absolutely, loose coupling can be very, very helpful.
Jon: Another point on why we do Event-Driven Architecture is its scalability. Another term that I learned right around the same time that I was learning about Pub/Sub architectures was “ilities”. These are scalability, maintainability, extensibility. There’s at least 10 others that I’m not…
Jon: Yeah, there’s a good one. Scalability, one of the good “illities” is helped by Event-Driven Architecture. How do we help scalability with Event-Driven Architectures?
Chris: The primary aspect there is just that by having the loose coupling and the fact that one component doesn’t have to know or support other ones. It means that as you scale-up and you have more dependent services or additional functionality, you can scale-up appropriately at the component level, you’re not applying attacks at the entire system level. You can individually scale-up things as you need them, where the load is the greatest. Again, decoupling here really helps out with that. You can apply to choose only where you need it, you don’t have to spread it out through the entire system because it’s all interconnected.
Jon: I think it’s worth talking about that, kind of from the point of view of APIs. I don’t know if I can do this justice, but if you see the entire world from the point of view of everything being a rest API, everything you do is a rest API and in order to get anything done, one service is going to call another service directly via a rest API. That creates a fairly tight dependency between one service and another.
Imagine you have the order system that we were talking about before; somebody goes and purchases their jeans. If that system had to know about the order fulfillment system, which is a separate system and say directly to that thing, “Hey, order fulfillment system, we just got an order. Just so you know, go do your thing.” It also had to know about like a customer survey system—just for lack of better thing thinking off the top of my head—so then it would also have to say to that thing, “Hey, we got a new order, get ready to do a customer survey.”
Maybe it also had to know about business analytic system, “Hey business analytic system, we got a new order.” so that the CxOs of the company can figure this out and look at how the company is performing later. That’s all of a sudden this one system is having to make three different API calls and each of those systems then also needs to make several API calls. You can start to see that you created a spider web of API call that are very very difficult to keep track of who’s calling who. I think that tackling that is getting rid of coupling, but it also helps us just kind of know what’s going on with our system a little bit. I don’t know if you can elaborate or fix any of what I said, Chris.
Chris: I think maybe what you’re alluding isn’t maybe like modularity and just kind of pointing out the fact that the more dependencies that you have, the more complicated it is to build something and maintain it. So, kind of being smart about your dependencies and keeping it to a reasonable size. I mean microservices helps out a lot here. There’s one service that’s responsible for a back in store and all requests might go to that microservice. You can do things like composability, when something needs to talk the multiple thing. I mean it’s a common thing. You can build APIs that compose the calls of those dependencies and encapsulate it so that you can do it in one place instead of many places in your system. Is that what kind of what you’re getting at?
Jon: Not quite. This is where the medium kind of fails us a little bit. We’re having a podcast here, I can’t show you the whiteboard, I can’t show our listeners the whiteboard, but maybe if I can paint a picture. If everything is a rest API and everything has to know about everything else then you get these… And if you had each rest API as sort of a dot and then each call between rest APIs is a line, and if everybody needed to know about everybody else in order to get their job done, then you create this picture that looks like a spider web, basically. All kinds of lines between all kinds of points, they’re all connected to each other and it’s very, very complicated.
What Pub/Sub or Event-Driven Architecture lets us do is create a different picture that looks more like a big sort of line that’s really thick that has a lot of information on it. All the different services are talking to that line, and then on the other side of it, they’re all kind of receiving information on that line. Instead of everyone talking to each other, everyone is talking to kind of a messenger. I’m hoping that you can kind of picture that in your mind what I’m saying. The actual graph of the architecture looks different, or the graph of the communication looks different, looks simpler, and that makes it easier to maintain, easier to talk about, and it’s maybe also easier to extend.
Chris: I think what you’re getting at microservices architecture obviously, we’re a fan of it. It definitely has its place but one of the downsides of it is by having many services, each doing basically one task really well, you then get that web of connections going in or amongst themselves. You may have like 8-core services that provide just basic platform services that other things then use and you do get this really complicated network of things and you run into issues like, “Oh, what happens if I do need to rev the API?” maybe it is a break and change for some reason like, “How does that even work?” It does get complicated.
There has been a little bit of a backlash there where folks will then go to like,”Well, the monolith is better. Let’s go back to the monolith.” I think what you’re kind of getting to maybe is more like thinking of this as kind of a pipeline or assembly line approach to doing the work where something comes in on the front end if you will. Some component sees that, does some unit of work on it, it’s kind of like it’s function-based. It’s just like input/output and then the output of that becomes the input to the next stage. Then ideally, each one of these stages, they don’t know about the other one, but in practicality, it’s hard to design something like that. It really doesn’t have any other dependencies.
There’s still a bit of that web of stuff but it’s conceptually, it’s a different way thinking things. Of course, that leads more towards a asynchronous system as opposed to a synchronous system. Again, different situations where it’s something like that would be useful, but it’s absolutely a common pattern that gets used in just about any kind of system we build especially things like, ETL, when you’re taking data, you’re extracting from one thing, you’re transforming it, and you’re loading it to something else. That’s the common pattern. It could be, you do some of this back of the house type things that suits itself or you could do things like communication campaigns, the analysis of it. There’s lots of situations where that kind of like functional input-output, output becomes the input to the next stage makes sense.
Jon: Well, we kind of got close there. Again, it’s hard to describe these things that are easy to draw, but I think one thing we’ve done as we’ve made it pretty clear what Publish/Subscribe is. Let’s leave it there and then next week, we’ll talk about how we implement it in AWS. Sound good?
Chris: Sounds like a plan.
Rich: Well, dear listener, you made it to the end. We appreciate your time and invite you to continue the conversation with us online. This episode, along with show notes and other valuable resources is available at mobycast.fm/33. If you have any question or additional insights, we encourage you to leave us a comment there. Thank you and we’ll see you again next week.