Update: I have received a ton of feedback on this post, and some of the well meaning criticism is concerned with the term ‘dysfunctional’, considering it a bit ‘judgy’ from somebody that is supposed to help these same teams. Apart from yielding a catchy title, Hacker News reader was spot on when he declared my use of the word as ‘term of endearment’ more than anything else. Not unlike a smart person calling herself ‘stupid’ or a workaholic calling himself ‘lazy’ for sleeping in one morning. In the proceeding article, ‘dysfunctional’ are most teams made from real people, and the opposite is the ideal we are all striving towards, always just beyond our reach.
I am back from Las Vegas and IBM Interconnnect 2015, and fully recovered from the onslaught on the senses. Man, does that city ever shut up. Time to return to regular programming. Today topic is my surprising realization of the main backers of micro-services in large enterprises. As they say in click baits, it’s not who you think.
For the last year or so I was a vocal evangelist for both Node.js and micro-services in IBM and elsewhere (using former as the platform of choice for the latter). Or as a dear former colleague of mine kindly put ‘evangelist, coach, and referee’. That role put me in contact with a number of teams finding themselves on the verge of the now familiar ‘from monolith to micro-services’ journey.
What I find over and over again is that micro-services appeal to leadership more than the developers. This is a somewhat confusing revelation considering micro-services are considered an architectural approach, and project managers are not supposed to fall in love with an architecture (at best, they are weary of it because ‘architecture’ is typically a code word for more boxes and increased cost and time to delivery). And yet.
Micro-services are not (only) about technology
When I am asked to do an elevator pitch about advantages of micro-services, this list typically comes to mind:
- Individually deployable pieces of running software each responsible for a small number of tasks
- Each micro-service can be implemented using a different stack
- Horizontal scalability decisions can be made at a micro-service level
When you analyze this list, neither point is really making your system better from a purely technical point of view. In fact, a monolithic system is definitely easier to work with when you are alone or have a small, ‘war room’ kind of a team. When a monolith is relatively small, deploying it is not a big deal, and cookie cutter scaling does not seem too wasteful (assuming the monolith does not depend on in-memory state that is hard to distribute).
Each of the points actually promises to fix long-standing systemic problems of very large teams responsible for equally large monoliths that are at the bursting point.
Breaking the logjam
The promise of individually deployable pieces seems to always light a fire in project managers’ eyes. I don’t blame them – most large monolithic systems are a bitch to deploy. If they use compiled languages such as Java, the build times are nontrivial. With every new line of code, deploy times keep growing, and it increasingly feels that there must be a better way to do this.
Monoliths are the first thing we build in the cloud because that’s what we used to do for on-premise deployment. Turns out, the price we pay to get the monolith built and deployed is too steep given the high bar set by ‘born in the cloud’ unicorns. Therefore, breaking up the monolith into smaller, more manageable parts seems as natural as mitosis is for single-cell organisms.
Beyond solving the sheer size problem, micro-services promise to solve the ‘different rate of change’ problem. As I have blogged recently, a typical system today have elements of Web sites, as well as Web apps rolled into one. Elements acting as a site have a tendency of wanting to change more often than the app part. Site sections tend to have a lot of marketing material that is time sensitive, while app sections are trickier and need to be changed more carefully (and may require data migration every once in a while). I often joke that these types of systems feel like a donkey and a horse strapped to the same harness – they just cannot find the right rhythm. One of them is either too fast or too slow. In fact, a lot of systems feel like we have a donkey, a horse, a cow and a goat all trying to pull the carriage together – not a pretty picture (funny though).
In these kinds of situations, micro-services offer an organizational, or governance solution, not a technical one. They often result in more moving parts and more complexity, but the relief of letting the metaphorical donkey and the horse run at their own pace is too hard to resist, overhead be damned. The alternative is having a complex process executed with utmost precision, and so far I know only one team (Facebook) that can pull it off with any regularity. Micro-services offer a more realistic alternative for the rest of us (the ‘dysfunctional teams’ from the title, which is really most of the teams).
No more intergalactic technology consensus
Anybody who tried to get a number of teams in a large organization to agree on a common technology can sympathize with this. We are all human, and tend to have passionate and strong opinions on technologies we like and hate. Put enough of these strong opinions together, and they tend to cancel each other out, leaving no common ground. This is bad news for the poor architect that needs to pick an approach for a large project. I once heard a saying learned through the hard won experience: “Even if we agree on a common technology or approach on Monday, we will slide back into disagreement by Thursday”.
In this context, micro-services offer not as much of a solution as “let’s just agree to disagree”. The focus is moved from common technology to common interfaces, integration techniques, protocols for passing data around. There is enough understanding about the advantages of stable protocols and APIs, so this part is much easier to close with a solid and lasting agreement.
A word of caution: I personally don’t think that, just because we could write each micro-service in a different technology, we should. There is much to be said about code reuse, and micro-services quickly minted by Yeomen generators tend to yield more productive teams than ‘let’s write the same authentication library in 6 different languages’. We found that by limiting our choices to Node.js and Java, we can move faster.
Nevertheless, it is just a matter of time until a new platform is touted as revolutionary or trending. When the time comes, we can risk one micro-service without betting the farm on it. Just in case Go does not turn out to be the giant killer it is touted to be, for example.
Cookie cutter is no fun with giant cookies
Finally, making clustering decisions at a micro-service level is more of a bean counter than architectural issue. Just clustering a small monolith is very simple – put a load-balancer in front of the monolith copies and you are done (again, assuming the monolith nodes do not critically depend on in-memory data that need to be kept in sync).
As the monolith grows, it needs more CPU and RAM to operate properly, times number of nodes. As it normally happens, ‘heat points’ are not distributed evenly across the monolith – there are sections that are working very hard, and sections that are barely moving. Cookie-cutter clustering becomes more and more expensive, with an increased percentage of unused and therefore wasted capacity.
Micro-services promise to be more efficient at using resources because we can make individual clustering decisions. We can beef up busy nodes and run a relatively small number of instances of rarely used micro-services. This is a purely economic (and ecological) issue – if we didn’t care about waste, we could just continue to run multiple monolith instances.
Of course, this is all assuming our monolith is clusterable to begin with. If it is not, micro-services become a way out for a system that has hit a limit of its ability to scale.
Keep the excitement to yourself
Next time you are in position to pitch micro-services to a worried project manager or product owner, don’t forget that technology is really not what you are selling – you are selling a solution for process, governance, cost of operation and scalability issues, not a technology. You are selling the ability to fix a typo on a prominent page of your large system within minutes without touching the rest of the system. You are promising the ability to maneuver an oil tanker as if it was a canoe, in a world full of oil tankers.
You can still be in love with the technology, just make it our little secret. I’ll never tell.
© Dejan Glozic, 2015