If you try to imagine an employee of a large organization who is supposed to run an entire business process on their own, from start to finish, and describe that hypothetical worker to anyone, it will definitely raise a few eyebrows. Indeed, it is strange to think that just one person should be in charge of, let’s say, purchases, accounting and maintenance at the same time.
However, until recently, it was perfectly normal to expect the same from an app. Monolithic architecture used to be the main approach to building an application, and a lot of apps are still built as a single service. Unsurprisingly, this approach can potentially cause many problems.
Microservices have been introduced as a new style of building software. The very name suggests that this approach is based on using multiple services in an app instead of just one, but how exactly does that work? Let’s find out.
Many of us still remember the times when apps were installed exclusively on the desktop. They were large and completely dependent on the resources of your own computer. The use of monolithic architecture back then made sense.
A monolithic app has a single code base, deployment unit, and tightly-coupled processes. This inevitably leads to multiple issues.
If you need to make even tiny modifications in a monolith, the whole app needs to be re-tested, because you never know which part of the functionality might suffer as a result of the new additions. When this approach is used for web apps, it means the app has to be offline for as long as you need to make sure everything works correctly. You also can’t scale only one process, the only option is to scale everything at the same time which is a waste of resources and money.
The first step to solving the problems of monolithic architecture was the introduction of service-oriented architecture. This approach involves separating the app into multiple services that correspond to certain business processes.
If you take an app for buying something online as an example, displaying the list of products and issuing the invoice for a purchase would be different processes. Respectively, different services would be responsible for managing and scaling them.
SOA solved the problem of scalability and allowed the modification and testing of each service separately, but it wasn’t a perfect solution. The main issue with it was the communication between services, which was organized via an enterprise service bus. Since it was the only way for services to communicate in the app, if the enterprise service bus failed, the whole app stopped working.
It was logical to expect further improvement, and so the more modern microservices architecture was designed. It is similar to traditional SOA in a number of ways, but it uses different, faster, mechanisms for communication between services.
Another difference is scope: SOA is often used as a broader term to describe standardizing the communication between web services on an enterprise level, while microservices architecture is generally associated with the application level. So let’s find out what else is special about microservices.
Microservices architecture has a number of prominent characteristics, but the main idea is to build an app as a combination of smaller, loosely-coupled units instead of a single monolith. Each of these units is a service dedicated to a specific business capability or process, like transferring a payment or generating an invoice.
Microservices are developed in a special way to work independently but communicate with each other. Instead of a single enterprise service bus, microservices use well-defined APIs for communication, as well as message brokers and event streaming.
Since each service has its own codebase, they can be written in different programming languages and utilize different technology stacks. As a rule, only a rather small development team is necessary to work on a single service.
Most often, microservices are divided into stateful and stateless categories. Stateful microservices utilize a database to store data which means additional storage is required. However, this type of microservice still functions independently, since the database is not shared between different microservices.
Stateless microservices don’t need extra storage because the data is not preserved. It exists only as a response to a request, and you can’t retrieve it once a specific request is complete.
What is truly important about microservices is that this way of app development facilitates the use of DevOps and CI/CD (continuous integration/continuous delivery) technologies. The way microservices architectures work is sure to bring multiple benefits for any project that employs it.
First of all, thanks to the services working independently, the failure of one service is not enough to bring down the whole application. The loose coupling of microservices leads to fault isolation, to a certain extent. It makes microservices far more resilient than older monolithic architectures.
Similarly, it is not necessary to take a whole microservices-based application offline to implement improvements or fixes. It is possible for each team to perform maintenance only on the specific service they support, while the rest of the services remain online.
Furthermore, apps that use microservices architecture are highly scalable, much more so than monolithic applications. Situations when just one business process requires more resources happen more often than when the whole app needs scaling. Having to scale only one specific service saves computing resources and decreases overhead for the organization in general.
Having a dedicated team working on each service separately ensures that software development and deployment become more agile. Small, cross-functional teams with domain knowledge that each work on a specific service can better focus and understand the context and achieve better results. Less time is spent on coordination between teams, updates can be deployed independently, faster and overall time to market becomes shorter.
You don’t need to complete the whole entire application before releasing it to the public; it is enough to build an MVP and add more services for extra features later.
Unlike with monolithic architecture, microservices don’t have to share every technology or tool. It frees up development teams to choose the best stack, database or data management model for the specific service they are building.
It also makes it easier to evolve over time, choosing the best cutting-edge technologies for new services based only on how well they meet the requirements for certain functionality.
Read our more in-depth article about the benefits of microservices architecture.
So microservices are perfect then? Well, they do have certain drawbacks too. The most obvious one is higher costs.
When you have multiple development teams working on separate services, the total number of employees can end up well beyond what you might have needed for just a single team working on a monolithic application.
Since the entire application consists of so many components, it also means end-to-end testing becomes more difficult, which can slow down the process of deployment.
Another defining feature of microservices architecture is its complexity. A distributed system requires more effort to set up in the first place. The freedom to choose languages and technologies could turn the decentralized approach into a hindrance - it can end up being almost impossible to manage all the different frameworks. Development teams will spend extra time on learning how to handle the new tools and technologies too.
Although microservices allow you to choose any preferred technology, there are certain tools and technologies that are so closely associated with microservices that it is important to mention them.
The first one is containers, originally introduced by Docker around a decade ago. Containers allow the creation of lightweight, isolated environments where microservices applications can run under specific conditions. Since containers don’t require their own operating system, unlike virtual machines, it reduces the overhead and makes them a great fit for the smaller services that comprise microservices architecture.
Another solution that helped the popularity of microservices to grow is Kubernetes. This open-source platform allows rapid management of the work of huge container clusters. You don’t necessarily have to use it if you want to adopt microservices architecture, but it definitely makes container orchestration easier.
How services communicate is the key to successful implementation of microservices. While direct communication between services and clients is an option, introducing an intermediary layer, like an API gateway, can be useful. It ensures extra security, performs authentication, and allows you to spread requests across other services for load balancing.
Although API gateways can be implemented with multiple technologies, if you have already decided to use Docker and Kubernetes for your project, then Ingress appears to be one of the most popular choices.
Choosing to stick to on-premises infrastructure wouldn’t prevent you from adopting microservices, however, there are two good reasons why microservices architecture is mostly associated with the cloud.
First, cloud services make it easier to manage an infrastructure in which each of the services might use a different technology stack.
Second, scaling components in the cloud can be significantly cheaper thanks to the possibility of deploying more resources only on demand, whenever necessary.
Even though microservices architecture has certain cons, more and more companies are moving towards it. For certain giant corporations, microservices have become the break-through solution that ensures they don’t have to stop growing.
One of the most notable migrations to microservices happened with Netflix. When this streaming platform shot to popularity more than a decade ago, at a certain point it became unable to provide its services without outages due to multiple scaling issues.
Netflix started the migration of the entire system from its non-user-facing systems and eventually refactored its entire architecture to microservices, transferring to stable distributed systems in the cloud. It allowed them to get rid of single points of failure like relational databases and ensure high-quality video streaming.
Fig.1 Netflix Deployed on AWS. Source
The cloud services provider that helped Netflix achieve its goals was Amazon. This company started its journey to microservices when its retail website’s customer base started growing quickly in the early 2000s.
Amazon originally solved its own scalability problem by developing service-oriented architecture and moved on to creating new, better solutions, like AWS, that now facilitate microservices architecture adoption for other companies.
The list of well-known companies that have adopted microservices includes Uber, eBay, PayPal, and Twitter, just to name a few. A number of large enterprises join them every day, as soon as their business needs outgrow the capabilities of their original, monolithic applications.
Microservices won’t likely replace monolithic systems completely in the foreseeable future. After all, monolithic architecture can work pretty well, if the entire application is small and doesn’t have a rapidly-growing user base.
Still, it is obvious that microservices architecture is a powerful solution for enterprise applications, as it solves multiple problems while making the whole custom software development process more agile.
Just make sure that you don’t adopt microservices only because it is somehow fashionable. Segmenting your application into services is a complicated and often expensive process, so the results should be valuable enough for your business, and align with business logic, to justify this decision.