Benefits of non-complex Microservice architecture
In order to determine whether microservice driven architecture is suitable for the development of your product or not, firstly we need to know what it offers. This should not be a unilateral decision but should be in consensus with the team, because it's the team that develops the product at the end of the day and therefore the team should be involved in this decision-making process. Irrespective of the outcome, it's the team that should own the decision and acts accordingly.
After exposing the problems that are caused by the monolithic architecture to your team/teams as in my article “Getting your team ready for Microservices: Part 1 - Why developing complex applications using monolith architecture is not a good idea?”, the next task is to expose the benefits and the drawbacks of using microservices driven architecture. In this article let’s go through the advantages that microservice driven architecture provides. You might not be able to leverage all the benefits offered by the microservices, but these advantages can be used in your discussion to bring forward the concerns and make an informed decision.
What is microservices driven architecture?
It is an architecture that supports building an application with loosely coupled services with clear interfaces/API and communications between these services are via HTTP, messaging etc. Each of these services is independent and may be written in different programming languages and possibly use different databases too. This is unlike a monolith application which is built and deployed as a single unit typically with just one type of programming language, one database and runs on one platform. There have to be changes made to enable the running of the same monolith application on the cloud platform.
Yet another motive to embrace microservices style is the capability it offers with respect to scale. This makes it very popular compared to monolith which gets increasingly difficult to scale as the modules/code/teams developing the software increase.
Yet another major advantage is the ability of microservices to be portable. Looking back this was one of the primary reasons Java became a very popular programming language when a java program is written in one environment it (bytecode) can be portable and used in any environment which provides JRE. Similarly, microservices should be portable to run and deployed in any environment - physical, cloud, containers etc.
Overall microservices architectures expose the potential of an application’s services to deploy and scale independently based on the need.
Break that complexity!
This is the most apparent benefit of using microservices driven architecture. Because this architecture gives us a way to break away from the complex nature of monolithic code which runs as single unit running on multiple servers, but instead, the microservices architecture forces us to think and develop loosely coupled services which integrate smoothly. These services or components are meant to run in a process of their own and thus render independence. Each service or component encloses business functionality and contains code to deliver this functionality in its entirety. That means to include all of the User Interface/Northbound Interface, business, database other layers needed. This warrants that the team is cross-functional and is capable of delivering the end to end service by itself. This will lead to more business driven decisions and a different way of working within teams/organizations, revolving around services & business capability.
The other benefits that can be seen when we avoid complexity are:
Faster Product development lifecycle
Embracing microservices architecture has a positive side effect: development and testing become so much easier, and if the deployment solution is simple enough, the whole life cycle of product development gets shorter. Designers can work independently on separate codebases rather than stepping on each other toes which would require huge coordination efforts.
Of course, there is an inherent complication because of this independence - as this gives autonomy to the services to use their means for internal and external communication. The communication between various services or the inter-service communication has to be fail-proof and performant. Thankfully, there are guidelines and patterns when it comes to writing services which will help us through these problems, one being “Be conservative in what you send, liberal in what you accept”, there are best practices with respect to using API gateway and other features which we will cover in the next few articles which we can use to our advantage.
When applications are based on microservices architecture, they do not need to spin up the entire application stack for a test environment, but just getting the relevant service to be spun up suffices.
With microservices, we do not have to follow the mandate to use the old testing strategy and old testing rules. Microservices sure will create modern thinking in terms of usage of tools and theories needed and applied. This further gives the development team complete autonomy to choose the scope of testing, type of testing and accordingly set up the vision of testing for the service being developed. There is autonomy in choosing the right type of functional and non-functional aspects relevant to the service. With freedom comes responsibility, it is fair to assume that the team tests the service in its entirety and the onus on the release verification or the QA verification teams which do a system level testing is confined to just the interface communication or testing non-functional aspects at a system level rather than the service level. The dependency on external testing/verification should be a lot reduced.
In fact, the teams can decide what is best suited to be tested pre-production and what suits for post-production kind of testing.
Because of the modularization offered by microservice architecture, software testing gets easier and as a result better and valuable tests can be written and tested before the product reaches the customer.
Fewer defects/easy troubleshooting
One of the reasons for fewer defects is due to the consequence of having modularized and good tests to cover them, write purposeful tests and the ability to effectively test end-to-end. As a result, very less defect slip through can be seen at the customer site. Each service (microservice) focus on a single functionality and this makes it easy to find out where the service has erred and to diagnose the problem. It can be evidenced by the fact that the ramp-up time decreases when we onboard new members and they are capable of debugging application very quickly.
On the other hand, if the code is not easy debuggable, it is the responsibility of the team to ensure they implement sufficient instrumentation and logging mechanisms to enable the right level of monitoring and troubleshooting.
This gives the team an opportunity to think how they have implemented the service: is it stand-alone or have they overlooked the “Single responsibility principle” of S.O.L.I.D (SOLID) or any of the other clean code principles. It is again the team's responsibility to make the code as easy or difficult to troubleshoot. But this complexity is significantly less as compared to debugging a monolith application.
No more centralized governance
With microservice driven architecture, the service coded by designers can be contained within their development environment. So this again leads to zero or less coordination for centralized environment services. Assuming the APIs exposed are agreed, each service can be tested using the resources as design environment provides.
We no longer have to use a single language or a framework to develop the different services in an application, but rather use the right technology for the right service. We can choose the right database that is optimal for the service instead of adhering to the centralized database. This can either be a relational database, Object-oriented database or even a NOSQL database. The database can be selected on what aspect of CAP (CAP Theorem) the service can trade off and a suitable decision can be made, without the need for choosing a single data management solution which is warranted by a monolith application. This decision can be based on what the data management solution is primarily planned to be used for - is it persistence, retrieval, performance or more of updating the data?
We can make such decisions even with the programming language used wherein each service can pick up the language that is best suited for the service. This is mainly because not all problems can be solved by a single programing language.
Upgrading to a new version of the 3PP or changing one of the tools used is totally isolated to your service.
This really does ensure autonomy in the team, where they need not go by some one’s defined PMD rules, check styles but do what meets their needs. The teams can define their own way of working that suits them without waiting on a consensus from the majority. This typically gives development teams an opportunity to up their game by exploring different technologies and gives room for healthy discussions within their teams. Remember at the end of the day, it's the development team that owns the code!
In summary, the benefits of just breaking the complexity are:
- Ease in software development
- Ease in ramping up new teams/ team members
- Fewer defects - more software development time
- Easy testing
- Easy troubleshooting
- Less maintenance overhead
- Easy understanding of the code - less ramp-up time
- Team autonomy
- Team empowerment
- Ability to choose the technology/3PP that is best suited
- Ability to choose the appropriate programming language
- Ability to choose the appropriate data management solution
- Less or zero intra-team coordination
- Focus on teams Way of working rather than the organization way of working
Of course, it's not just the ease that microservice driven architecture promises, there are other benefits too which I will try to cover in the next few posts.