What is a Microservice Architecture? Why is it important now?
We have been building software applications for many years using various tools, technologies, architectural patterns and best practices. It is evident that many software applications become large complex monolith over a period for various reasons. A monolith software application is like a large ball of spaghetti with criss-cross dependencies among its constituent modules. It becomes more complex to develop, deploy and maintain monoliths, constraining the agility and competitive advantages of development teams. Also, let us not undermine the challenge of clearing any sort of technical debt monoliths accumulate, as changing part of monolith code may have cascading impact of destabilizing a working software in production.
Over the years, architectural patterns such as Service Oriented Architecture (SOA) and Microservices have emerged as alternatives to Monoliths.
SOA was arguably the first architectural pattern aimed at solving the typical monolith issues by breaking down a large complex software application to sub-systems or “services”. All these services communicate over a common enterprise service bus (ESB). However, these sub-systems or services are actually mid-sized monoliths, as they share the same database. Also, more and more service-aware logic gets added to ESB and it becomes the single point of failure.
Microservice as an architectural pattern has gathered steam due to large scale adoption by companies like Amazon, Netflix, SoundCloud, Spotify etc. It breaks downs a large software application to a number of loosely coupled microservices. Each microservice is responsible for doing specific discrete tasks, can have its own database and can communicate with other microservices through Application Programming Interfaces (APIs) to solve a large complex business problem. Each microservice can be developed, deployed and maintained independently as long as it operates without breaching a well-defined set of APIs called contract to communicate with other microservices.
What are the advantages of Microservices architecture?
1.Development Agility: As large complex software applications are decomposed to a number of small microservices, each microservice can be developed by small “one-pizza” or “two-pizza” teams independently. The teams can plan, build, deploy and maintain their microservices independently as long as the service boundaries are well-defined, and no breach of contract is ensured. The teams become more responsive to changes.
2.Technology Stack Independence: In a typical monolith, the constituent modules have “compilation or build dependency” and share capabilities as “libraries“. Any changes in one module triggers compilation and/or linking of the whole software application. So, it basically implies and mandates to standardize the technology stack (such as programming language, database etc) to develop a monolith software application.
In contrast, a microservice can be developed, deployed and maintained as a small independent application without any compilation or build dependency with other microservices. Its dependency with other microservices is handled through well-defined APIs or contract. It means that each microservice can be developed by choosing any technology stack (programming language, database, etc) best suited to realize its functionality instead of being required to take a more standardized, one-size-fits-all approach.
3.Managing Technical Debt is easier: Let us say we find that one microservice is not vertically scaling in production. We can localize and fix the issue by modifying specific implementation part of that microservice code. Alternatively, we can choose to rewrite the microservice with a different technology stack best suited for meeting the vertical scaling goals. In either approach, as long as the consumer contracts the microservice shares are upheld, the development team is free to change the implementation without impacting the larger system.
4.Improved Fault Isolation: In case of an error, a whole monolith application can crash and disrupt business as usual (BAU). However, microservices architecture offers improved fault isolation whereby in the case of an error in one service the whole application doesn’t necessarily stop functioning. When the error is fixed, it can be deployed only for the respective service instead of redeploying an entire application.
For example, in a typical eCommerce application, let us say, the “product review service” is down; as a result, users will not able to read product reviews or write new reviews. But it has not impact on other services such as “product catalog management service”, “order management service” etc; as a result, users can still search, add products to cart and check-out.
5.Scaling of Hot Services: Once developed, microservices can be deployed independently of each other. It helps in identifying “hot services” and design to scale them independent of the whole application. Similarly, microservices architecture enables auto scaling of different services resulting in optimal usage of precious computing resources. In contrast, a monolith hogs computing resources, as the whole application keeps running even though some modules are dormant.
What are the limitations of Microservices architecture?
If not designed carefully, microservices architecture also can become complex. Hence, certain design principles and practices must be considered.
1.Boundary of Microservices: We need to be careful while defining boundaries of microservices. They should neither become monoliths nor be so small that it results in exchange of large volume of API calls, choking the network and degrading the performance of whole application. Domain driven design helps in defining the boundaries. Also extend Robert Martic C’s “Single Responsibility Principle” which states – “Gather things together that change for the same reason and separate things that change for different reasons”.
2.Build and Deploy: Once boundaries are defined, a microservice should be built by a single team that can decide the best technology stack to realize its functionality. The dependencies among microservices are defined through well-defined APIs or contract. Ideally, they should run perfectly as long as the contract is upheld. However, the ideal scenarios are far off from ground reality. APIs or contracts evolve continuously in the form of different API versions and it may lead to break down of the application. Hence it is essential to setup CI/CD pipelines with any of the available CI servers (like Jenkins) to run the automated test cases and deploy these services independently to different environments (Integration, QA, Staging, Production, etc)
3.Monitoring and Logging: Microservices are distributed by nature and monitoring and logging of individual services can be a challenge. It’s difficult to go through and correlate logs of each service instance and figure out individual errors. So, it makes a lot of sense to implement a common “log & statistics aggregation service” to monitor and control all the microservices centrally from a control panel.
Microservices architecture and Agile software development have a lot in common.
Just as microservice architecture is frequently defined in contrast to monolithic architecture, the agile software development approach removes the overhead and risk of large-scale software development by using smaller work increments, frequent iterations, and prototyping as a means of collaboration with users.
Agile software development with continuous delivery, devops culture and microservice architecture are all bound by a common set of goals – to be as responsive as possible to customer needs while maintaining high levels of software quality and system availability; in other words – to be agile.
Have you built software applications using microservice architecture? Have you decomposed a large monolith to a number of microservices? If so, please share your challenges and best practices in the comments.
Looking to leverage technology effectively to thrive in the digital era? Our CTO focused set of solutions is what you need.
Panchanan Pradhan is the VP, Head of Engineering & Product Delivery in Subex. He is responsible for leading the product development / engineering organization at Subex, for design & delivery of next generation Subex products and solutions. Prior to Subex, he worked in Huawei Technologies and Nokia in end to end product development and engineering delivery in BSS/OSS domain. He holds a bachelor degree in Computer Science & Engineering from National Institute of Technology (NIT), Calicut.