Book Review: Monolith to Microservices (Part 2)

Posted on by

Categories:       

This is the second article that of the first one I wrote the other day on, “Monolith to Microservices: Evolutionary Patterns to Transform Your Monolith” by Sam Newman. In this article, I will summarize chapter two.

##Chapter #2: Planning to migration

In this chapter, the book discusses the goal and mindset. When we are looking for a Microservices, what should be our goal. It argues that our goal shouldn’t be the Microservices. Something worked for Netflix or Amazon, which means it will work for me as well. This thought process has a major flaw. It makes you fall into a cargo cult mentality. Every set of problems are different and can be further varied upon the situation, the resources we have at our disposal. Every decision has its cost. Nothing comes free. I cannot simply copy ideas from Amazon or Google and apply them to my cases. Before adopting Microservices architecture, we should ask three questions -

What are we hoping to achieve? First, we must have to have a clear understanding of what we are trying to accomplish with this architecture. It shouldn’t be the case that we are doing it because it’s cool or everyone is doing so. Have we considered an alternative to Microservices? Before delving into it, we should consider other approaches because we can often achieve what we want to accomplish without Microservices. How will we know the transition is working? First, we have to have figure out a way to validate that we are in the right direction. We will discuss this in chapter #5 later. Now that the questions are out of the way let’s discuss why we consider Microservices, which aligns with our goal.

Improve Team autonomy: Having Microservices enables us to have to create autonomous teams. Keeping a team small, allowing them to build close bonding and work effectively together without bringing in too much bureaucracy, in turn, help the organization grow and scale more effectively. We can consider amazon’s two-pizza team model. Usually, team autonomy can empower people, help them step up and grow and get the job done.

Alternative to Microservices, giving ownership to parts of the codebase to different teams, we can achieve this sort of autonomy to the groups, e.g. modular monolith can be a perfect answer here.

Reduce time to market: by able to make and deploy changes independently, it requires less coordination between multiple teams; thus, it reduces the time to put things out for actual use.

Alternatively, with proper automation suites, highlighting the pain point can help reduce the time to market.

Scale Cost-Effectively for Load: since things are now broken into smaller pieces, it’s now easy to scale independently. In a complete system, the idea is that not all parts would require handling huge loads, so we can focus on those parts that need it. That gives us more control over operational costs.

Alternatively, vertical scaling can help to a great extend. Horizontal scaling -basically running multiple copies- could prove to be highly effective,

Improve robustness: The expectation grows when we move from a single talent software to a multitenant SaaS application. For example- the application must be available all the time. However, since in Microservice, the application is decomposed into multiple smaller pieces, an impact on a particular area doesn’t require putting the whole system down. Thus, it reduces the blast radius; if something goes wrong, the affecting area becomes granular, and we can focus our energy on that small piece and fix it quickly.

Alternately, we can put multiple copies of the monolith behind the load balancer, or a queue can improve robustness. Distributing instances of the monolith across multiple failure planes can also further help to handle failure gracefully.

Scale the number of developers: We all know it doesn’t work putting many developers at a project. The joke “one developer does a job in a month; two developers do it two months” is well known. However, if we can partition things into separate independent work units with less interaction between them, then it works. With clear boundaries and Microservices architecture, it is easy to scale developers' productivity with more developers in the organization.

Alternatively, moduler monolith can also help to achieve the same principle. Each team can have one module and work independently as long as the interface with the module remains stable.

Embrace new technology: Although mature organizations limit how many technology stacks they support, it opens the door to having more than one stack running for multiple services. It even makes developers happy to some extent.

Alternately, we can safely adopt a new language if the runtime remains the same. For example, JVM can run code written in multiple languages within the same running process. E.g. Groovy, Scala, Kotlin, Java, Clojure, JRuby, etc.

Now that we have understood the goal of having Microservices, let’s discuss when the this isn’t really a good fit.

Uncertain Domain: Getting service boundaries wrong can be extremely expensive. It can lead to an overly coupled component, in general, could be worse than a monolith. So if we don’t have a full grasp of the domain, we must first get the domain expertise before coming to microservices.

Startups: Usually, a startup is like to have limited funding and resources, where things start with experimenting with ideas; it’s probably not a good idea, to begin with, microservices. A company like Netflix, Airbnb didn’t start their product with microservice in the first place; rather, they moved to it gradually. When a startup experiments with its idea, if the idea doesn’t work, it doesn’t really matter if its software architecture is great.

Not having really good reasons: Doing microservices just because everyone else is doing it is a terrible idea. If we don’t have a clear idea of what we want to achieve, we shouldn’t go for microservices.

Now that we have laid out the whole picture, it’s your call to decide whether you want Microservice or not. In many cases, microservices are probably not ideal, but if you’re going to do it with all the good reasons we mentioned, take the baby steps. First, create some strategy to onboard the team to develop a vision and plan towards it. Small and short-term wins matter; it boasts up the team’s confidence. Put things in production. Always put checks and balance whether it is working or not. If not, then go back to the alternative ways. Don’t go for a big bang rewrite; as Martin Fowler stated, if you do a bing-bang rewrite, the only thing you’re guaranteed of is a big bang.

That’s for today; I will write about the next chapter in the following article.

   

Share on:

Author: A N M Bazlur Rahman

Java enthusiastic | Book author | Mentor | Helping Java Developers to improve their coding & collaboration skills so that they can meet great people & collaborate

100daysofcode 100daysofjava access advance-java agile algorithm arraylist article bangla-book becoming-expert biginteger book calculator checked checked-exceptions cloning code-readability code-review coding coding-convention collection-framework compact-strings completablefuture concatenation concurrency concurrentmodificationexception concurrentskiplistmap counting countingcollections critical-section daemon-thread data-race data-structure datetime day002 deliberate-practice deserialization design-pattern developers duration execute-around executors export fibonacci file file-copy fork/join-common-pool functional future-java-developers groupby hash-function hashmap history history-of-java how-java-performs-better how-java-works http-client image import inspiration io itext-pdf java java-10 java-11 java-17 java-8 java-9 java-developers java-performance java-programming java-thread java-thread-programming java11 java16 java8 lambda-expression learning learning-and-development linkedlist list local-type-inference localdatetime map methodology microservices nio non-blockingio null-pointer-exception object-cloning optional packaging parallel pass-by-reference pass-by-value pdf performance prime-number programming project-loom race-condition readable-code record refactoring review scheduler scrum serialization serversocket simple-calculator socket software-development softwarearchitecture softwareengineering sorting source-code stack string string-pool stringbuilder swing thread threads tutorial unchecked vector virtual-thread volatile why-java zoneid