Microservices are the new cool kids in tech town and everyone's trying to join the party. After all, microservices are considered the panacea that brings speed, agility, and innovation to software powered businesses.
For the most part, this is true. In Part I of my four blog series, we will take a look at how software architecture has evolved over the years and why you should consider adopting microservices.
How did we get here?
Software architecture has considerably evolved since the beginning of this century. We started with monolithic architectures where an application was packaged in one big file. Monolithic apps seem as antiquated as rotary dials now, but it was the primary architecture used in the 90s, when most software was only installed as a desktop client and was refreshed once every couple of years at the most.
As applications started becoming more complex and businesses started seeing faster releases as a way to win against the competition, application architectures became increasingly componentized and decoupled. This process was also helped along by other disruptive ideas like virtualization and cloud native applications. All these shifts were mutually symbiotic and led to more agility and faster innovation, resulting in companies like Netflix which have the ability to ship changes to production multiple times daily.
N-tier apps, Service Oriented Architecture (SOA), and microservices are just steps in this evolution where components are getting increasingly smaller and more decoupled. The next phase of this evolution is Serverless architecture and Amazon has already made a big bet in this space with AWS Lambda.
The benefits of microservices go well beyond faster innovation, like leading to better hiring and cost efficiency. Lets look at this in greater detail.
The Benefits of Microservices
According to Martin Fowler:
The microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.
To put it in layman's terms, you break down your application into small services that each perform one business function and can be developed, deployed, and scaled independently. This approach leads to the following benefits:
Agility and Speed
Adopting microservices brings agility and speed to application development because of the following reasons:
- Each microservice is independently developed and maintained by a small team. Since it only performs one business function, the codebase is simple and every member of the team understands it and can change it quickly.
- The team working on a microservice doesn't just control the full stack dev, they also own deployment of the service. Since every service is decoupled with other services, it frees the team from co-ordinating across teams in different time zones and dealing with the chaos that comes with it.
- Any updates to the microservice can be tested independently since it is decoupled from other services. The test matrix is therefore small and can be executed much faster.
- The best language and tools can be chosen depending on the requirement for that specific microservice. At Shippable, we could rewrite our code coverage parsing microservice in Go even though most of the other services are written in Node.js.
The general rule of thumb for determining scope for a microservice is that a 2 pizza team should be able to completely own it end to end, including development, maintenance, testing, and deployments.
With large, complex codebases, bugs are often passed around between teams with nobody admitting to it being their bug. With microservices, bugs can be tracked down and fixed easily since the codebase for each microservice is fairly small and well understood by everyone on the team. This means that more bugs can be found and fixed for each release.
Businesses are laser focused on making sure their development and hosting costs don't bloat as they develop more complex applications. Microservices help control costs since each service can be scaled independently as required. At Shippable, test and code coverage report processing is very intense and takes time. Any time we see the reports queue building up, we add a few instances of just those microservices until the queue is small again. This would never be possible with other more tightly coupled architectures which would require scaling up everything together.
We've all dealt with pesky bugs that bring down our applications and get us further and further away from the holy grail of 5 nines. With microservices, most bugs only affect a single service and the rest of the applications still works normally. The smaller codebase also makes it easier to track down and fix bugs. For example, if our Notification microservice goes down, build still work normally, but and the impact is limited to users not being notified about build results.
The other nice thing is that you can define different availability targets for each service, depending on the impact to customers.
Microservices enable you to hire better teams by removing several constraints around hiring decisions. This is mainly since each microservice is developed independently, so you can hire that Ruby expert to write a service even if most of your services are written in another language.
That's the overall picture when you're wearing rose tinted glasses. What's the flip side? For an in-depth look at the challenges around microservices, stay tuned for Part II.