views
Remember the old black and white flicks where the computer was depicted as a massive machine, usually in the basement, all whirring wheels and blinking lights? Well, those old movies had the size right. Back in those days, we’re talking about the 1980’s here, before computing began to go mainstream, monolithic applications lived on mainframe computers. Then, only organizations with deep pockets could afford these computers. This did give them some advantage but it didn’t come cheap, nor was it particularly speedy, as it often took hours to receive the output of a program. And if the program had a bug, the user would know about it only after a couple of hours. And only after the required corrections would be made, would the computer churn out output.
Those applications integrated everything—including the hardware. UI, business logic, utility programs, and even the database were totally integrated into the application itself. The reason it was so inefficient was that the entire hardware and software were shared by multiple users and background processes.
These applications were the forerunners of present-day monolithic applications, and the inefficiencies drove the creation of microservices architecture. To understand microservices and how they have disrupted IT, we need to understand the differences between each and what led to the move from monolithic to microservices.
Monolithic applications
When the functionalities of a project are integrated into a single codebase, that application can be described as a monolithic application. The clue is in the name itself: mono, meaning single (in this case, a single codebase, which contains all the required functionalities for the app to run) Typically, the application is designed with various layers like presentation, service, and persistence and then deployed with the codebase as a single jar/war/lib/binary file. So far so good? Well, not really. There are several disadvantages to this type of application, as listed here:
Disadvantages of Monolithic applications
As organizations grow and their needs evolve, the application becomes too large and complex, making it difficult to manage.
If a single small change needs to be made, the whole application must be retested and redeployed.
With the increase in functionality and size, the application’s start-up and deployment time also increases.
It is very difficult for a new developer (even if his responsibility is related to a single functionality) to understand the logic of a large Monolithic application.
Horizontal scaling is not feasible, as multiple instances of the entire application have to be deployed is a single part of the application encounters large load/traffic. This is very inefficient and resource-intensive.
If, for instance, there is some new technology that is well suited for a particular functionality, it is, nevertheless, difficult to employ, as it affects the entire application, both in terms of time and cost.
Monolithic applications can be unreliable as even a single bug in a single module can bring down the entire application.
But it’s not all doom and gloom. Monolithic applications do have several advantages, which is probably why they are still used.
Easy/straightforward development (compared to microservices)
Easier to deploy, since it uses one single codebase, viz. only a single jar/war/binary file needs to be deployed.
Fewer problems of latency, as all the functionalities exist in one place
Better security (in comparison to microservices), as the application parts are all in a single place.
The disadvantages of monolithic applications led developers to split the services that were integrated into one codebase. This allowed easier scaling and deployment. This type of architecture, which became quite popular in the early 2000’s came to be known as Service Oriented Architecture (SOA).
Service Oriented Architecture
In an SOA, the large application is broken up into multiple smaller services, which are deployed separately. These applications follow a principle known as loose coupling, i.e. the design ensures minimum dependency on each other. This allows services to be used at a specific capacity even if one of the dependent elements goes down.
While the reusable components are a time saver in the development process, it also means that if one component does down, all the systems that use that component will also fail. This is a big point of difference between SOA and microservices. An SOA system handles multiple tasks, whereas each microservice is responsible for only one single task (aka, single responsibility principle). Furthermore, SOA services don’t communicate with each other directly, they used an Enterprise Service Bus (ESB). It is possible to do away with the ESB and have the services communicate directly but this can complicate the development process and raise costs, too.
So, while SOA resolved some challenges posed by the monolithic approach, deployment, updates, scaling, etc. were still an issue. This led to the evolution of the microservice architecture.
SOA vs Microservices: High Level Differences | |
SOA | Microservices |
Each system can handle multiple tasks | Single responsibility principle |
Not as scalable as microservices | Highly scalable and flexible |
Primarily about resource sharing | The primary purpose is to exclude all dependencies |
Loosely coupled (compared to monolithic apps) | Significantly more loosely coupled than SOA |
The biggest noticeable difference between monolithic applications, SOA, and microservices is the uncoupling of services. Although this is true for SOA as well, microservices are far more loosely coupled than SOA applications, because each microservice is responsible for just one specific task. This is possible, in large part, because each microservice has its own database, unlike monolithic or SOA architectures where databases are shared.
Having discrete databases does lead to some duplication of data, but having a database per microservice ensures loose coupling. Furthermore, since microservices each have their own separate database, they can use the type of database that best suits each one’s needs.
Principles of microservices
- Single responsibility: This is one of microservices’ design’s basic principles, wherein each microservice has one and only one responsibility or functionality. In other words, the number of microservices that each application should comprise is equal to the number of functionalities needed.
- Decentralized database: As described earlier, this is necessary for each microservice to function independently.
- Diverse tech-stack: Given the abundance and diversity of technologies in today’s world, there is always a technology that is best suited to implement a particular functionality, and microservices architectures leverage this to the fullest, allowing developers considerable autonomy if choosing preferred technologies. This was not possible in monolithic applications, and led to compromises, as developers were not able to use different technology for each functionality.
Microservices, on the other hand, are never restricted from adopting the best-fit technology stack or backend database storage to meet the business’s requirements.
- Designed for failure: Microservices, ideally, should be designed in a manner where the failure of one does not affect the whole system, or indeed, any other microservice. This was not the case in the Monolithic applications, where the failure of one module inevitably led to the whole application failing.
Microservices advantages:
- Easy to manage a specific micro-service, given its smaller size
- Easy to deploy The entire application doesn’t need to be stopped to deploy an update in one of the microservices; only that particular microservice needs to be redeployed and that too with zero downtime.
- Easy to onboard a new developer, as he doesn’t need to understand the whole system, the microservice providing the functionality he is responsible for.
- Easy to scale When and if a particular service is facing a heavy load, only that particular microservice needs to be scaled…for instance, shopping carts experience far more loads than say user registration. In this instance, only the microservices responsible for shopping carts need to be scaled. In other words, the microservices architecture supports horizontal scaling.
- Freedom to use best-fit tech-stack Since each microservice has a particular function, and the microservice is basically designed for autonomy, there is no restriction on adopting the technology that best addresses the business requirements.
- Easy to debug In the event a bug infects the application, just that particular microservice goes down and can be individually addressed. It doesn’t affect other microservices as they continue to provide other functionalities, ensuring the system doesn’t go down as a whole.
Disadvantages of microservices:
While there are many clear advantages to using microservices, there are some downsides too.
- Increased complexity: As a distributed system, microservices are much more complex than monolithic applications. And this complexity increases as the number of microservices within the application increase.
- Specific skill sets: Developers working on microservices architecture must have special skill-sets, such as being able to to identify microservices and manage their inter-communications.
- Debugging a microservice is easier: in theory, it can be complicated in practice, as the control flows over many microservices, and pinpointing why and where exactly the error occurred can be a tedious task.
- High network demands & increased latency: microservices’ network usage is costly, as the microservices need to interact with each other and all these remotes bring network latency.
Less secure (compared to monolithic applications) because of inter-services communication over the network.
Conclusion
It’s never simple to build any application, and the complexity increases as the application grows larger or more evolved. Monolithic architectures are thus better suited for simple, lightweight applications, while microservices architectures are a better choice for complex, evolving applications. Some experts are of the opinion that it is more logical to start with the monolithic application first; while others recommend going directly with a microservices approach if that is indeed your goal. Whatever the case, it is important to understand the principles governing monolithic architecture as it is the starting point for microservices architecture.