Architecting Manchester — Breaking up the Monolith
What an amazing evening at the Architecting Manchester event. It is always a great experience to talk with other like-minded individuals about how they tackle technical architecture and dev ops.
What is Architecting Manchester?
Architecting Manchester is not your typical tech event. The majority of tech events around Manchester involve a bunch of techies getting together to hear talks from experienced people about a variety of topics around different technologies.
The event is different because it is a group discussion about a given topic — with this months topic being all about moving from monolith to micro-services.
Although this event is mostly centred around technical architecture, there are attendees with a range of different roles. These include software engineers, product owners, heads of development, CTOs. Granted, these are all technical roles…but it is great to see people willing to expand their knowledge outside of what their usual day-to-day role requires.
What was the discussion about?
So the discussion was all about micro-services. There were a bunch of questions on the whiteboard…although I feel that we may have gone off on a slight tangent from the original question 😅
However, we did manage to cover 3 of these questions.
How to identify what to break out?
So you already have a monolith, but you want to start migrating bits of it away so that you can leverage micro-services. But where do you start?
The temptation is to take a small bit of code that is already self contained and make that a micro-service. But I think you should stop first, step back, and think practically. Just because you hear the word “micro”, it doesn’t necessarily mean “small”. So try not to focus to much on the size of your micro-service.
Start by identifying your bounded contexts. These are areas of your application that talk to each other. For example, you will have a part of your code that adds products to a shopping cart. However, sometimes bounded contexts will not always be easy to find.
What problems do micro-services solve?
There was a lot of talk about the ability to attract talent by using the word “micro-services”. So one of the advantages may be that potential recruits will think more highly of you compared with other companies.
It can also be intimidating for a new developer to come in and start trying to get their heads around a monolithic application. So if the application can be split up into manageable chunks then it will (in theory) keep the developers better engaged and productive.
It also makes it a lot easier to conduct code reviews, because you know that one micro-service is not going to talk to the internals of another. That is one of the caveats of working with a monolith. It is often tempting to reuse code that you shouldn’t…
Micro-services are also a great fit when you have an increasing number of developers in your company. Working on a monolith with lots of developers can be frustrating at times. Especially if you have them working on the same area…merge conflicts 🖕! When you have teams working on different services it is a lot easier to release new features without having to worry about scheduled merges and releases 👍
Deployment time is also faster, which results in being able to scale in no time at all. It also means that if (for whatever reason) you release a micro-service that hasn’t been properly QA’d, and it starts breaking everything, then you can quickly revert to a previous release. But of course you need to have processes in place to make that an easy task too.
What problems do micro-services cause?
Micro-services aren’t perfect. They have their flaws. And I think one of the main issues that most people have with them is that you have to focus more on orchestration. With a monolith it is really easy. You have a deployment pipeline for a single application. So you could change a bunch of code in different areas of the codebase and release with no fuss. However, if you want to make a change to your bounded contexts (please don’t), then you will have to orchestrate the deployment of multiple services.
Diagnosing issues with micro-services can be a new experience for you. You have to work out a new way of logging. So you could use correlation IDs to track a request that passes through your collection of micro-services in order to pinpoint where something hasn’t gone quite right. Without adequate logging you will be in the dark about what your micro-services are doing. Which is why you should log all the things by default.
Here is what I took away from this event.
Use micro-services at the start?
I am still unsure if this is a good idea. There were talks that it is an advantage to go straight down the micro-services route because you avoid the pitfalls of a monolithic application early on. One of the pitfalls that comes up time and time again for monolithic architecture is the fact that you can start introducing tight coupling around different areas of your application.
I think the route you go down depends on the size of the team. If you have a team of 5 developers, then I think a monolith is far more practical. However, you should always try to ensure that you don’t end up tightly coupling your code. This will make it a lot easier when you do come to start extracting micro-services out of your monolith. You can literally start taking chunks out of your legacy application and start reaping the benefits of having scalable, specialised and isolated services.
Keeps the team motivated
Another interesting point was made that pitching your company to new hires is a lot easier when you say that you have a micro-services architecture. You can sell the fact that they can work in a truly autonomous team. And they they have ownership of a particular service (or set of services).
It also means that developers don’t need to understand a massive application. They only need to understand a small section of it. Let’s face it…a large codebase can be quite intimidating. A caveat of this is that they may not have a picture of the world as a whole, but that can be solved by allowing developers to move between service teams in order to gradually expand their domain knowledge.
Expanding on the concept of ownership — giving a team that responsibility gives the business greater comfort in knowing that the team will focus on building a quality (and hopefully robust) service that can start adding value. When working on a monolith the accountability for any failures is more distributed due to the greater number of moving parts.
More decoupling = More communication
The benefit of using micro-services is that you allow your teams to be more productive. There is less of a requirement to know how an entire system works if you have a team that is responsible for a particular service. They just need to focus their efforts on making it fulfil requirements and provide a consistent contract for other services to hook in to.
Having said that…most of the time micro-services do end up needing to talk to each other. So that does require a bit of extra communication between teams that work on other micro-services. You don’t want to be in a position where a team decides to change the interface into a micro-service without telling anyone…
I think this is one of the main advantages to using micro-services.
- Deployment time is significantly less than a monolith (mostly)
- Fixes can be released quickly
- Deployments can be reverted quickly
- Specific services can be scaled during times of increased load
- You can spot failures easily (as long as you are logging all the things)
You can do these things with a monolith…but deployments take an increasing amount of time as the application gets bigger. Also, scaling a monolith means that you are also scaling areas of the application which may not be subject to increased load 😅
Most people are aware that there are cases where the choice between monolith and micro-service is based on requirements (and quite often timescales). Personally I like creating a monolith to begin with, but ensure that the application has internal bounded contexts so that when the time comes it is easy to start migrating sections out into micro-services (until the monolith itself becomes a micro-service).