In the world of software development, there are a lot of software architecture patterns that emerged as a result of expert developers figuring out the best way to solve certain problems in their line of work.
In this multipart series on Introduction to Software Architecture Patterns, we will be looking at some of the common patterns such as:
- Broker patterns
For the first article, we will be looking at microservices in detail and describing what it is, what it is not, the pros and cons of it, and when to use it.
What is a microservice and what it is not
Microservice is now one of the most hyped software architecture patterns in the tech industry. Maybe you read about it from some tech news or articles. Or maybe you heard about it from your colleagues who happen to read about it. Maybe your boss ask you to design the company’s next software project as microservices and you are scratching your head.
So what is it really?
In its simplest form, it is a variant of the service-oriented architecture style that arrange and structure a software system as a collection of loosely coupled services.
It can also be said that a microservice takes the single responsibility principle coined by Robert C. Martin to the next level by applying it to the loosely coupled services which can be developed, deployed and maintained independently. Each service is built specifically to work on a discrete task and can communicate with the other services through simple API to solve complex problems.
From the description above, microservice seems simple enough to understand. Yet there is no universal definition on what it is. Different industry experts have a differing opinion on it, but as time went by, they came to a consensus on what are some of the defining characteristics of a microservice.
- Services in a microservice architecture are processes that communicate over network using technology-agnostic protocols such as HTTP.
- Services are independently deployable
- Services are organised around business capabilities
- Services can be implemented using different programming languages, databases, hardware and software environment
- Services are small in size, built with messaging enabled, bounded by context, autonomously developed, decentralised, built and released with automated processes.
Now that we know what is a microservice, we will take a look at some of the advantages of using a microservice.
The microservice architecture comes with several advantages that make it a better option for developing applications but only if it is done correctly and properly.
Resilient to partial service failure
The biggest advantage microservice architecture can offer when compared to the other architectures is that any given service for an application should be able to continue operating even if some others goes down due to software bug or crashes. This is because each service are designed and built to be mostly self-contained and autonomous.
Highly maintainable and testable
The modular nature of a microservice architecture meant that each service is small and specialised. A service can then be easily replaced, changed or updated without affecting the rest of the application.
Furthermore, the developer responsible for the service can also easily test it. They would not have to deal with a large and unwieldy application that would inadvertently happen as the application expands in its capabilities or go in depth into the other areas of the application to understand the business just to test their changes.
One of the biggest problem with traditional monolithic architecture is that the application could suffer from a vendor lock-in due to the type or kind of technology used. This creates problem when the vendor goes out of business or the pricing for continual use of the vendor’s product rises beyond what makes sense for the application. Attempts to change the application to use alternative technology or platform can be very costly.
With a microservice, services are loosely coupled from each other. Each service can choose to use different technology or run on different platforms. In the event that a particular service needs to change its technology stack, the team which is responsible for it can do so without affecting the others. Furthermore, the loosely coupled nature also meant that any source code changes would be kept within each service and do not propagate to other services.
Since services in a microservice are loosely coupled and each could come with their own storage mechanism, there is no real need for a service to wait for the others to go offline or go online before it could be deployed.
Organised around business capabilities
When done properly during the initial phase, each microservice would be designed, developed and deployed to solve problems in a specific business domain (eg. customer relationship management, sales order management, invoicing). Developers can be hired and organised such that they could focus on solving problems in that business domain, creating products instead of projects and writing glue codes. This could translate to having developers who are responsible for a specific or a few service(s) and they develop expertise in that area of the business, leading to faster turn around of new features. The final product or service could also be reused in a different process, other contexts or channels, which would lead to cost savings for the organisation since there is no need to green-lit new projects and hire new developers.
Owned by a small team
By breaking down an application into smaller but autonomous services, teams can become smaller and more efficient. There is no need to have dozens of software developers, managers and support staff to run a service. With the service smaller than a monolithic application, its startup time in the production environment will also be faster and so will the development environment the developers used. With that, they can be more productive and focus on delivery of bug fixes, features and improvements.
Furthermore, they would be responsible for understanding the requirements, developing the necessary features, testing, deployment and support. This will give them more ownership and allow them to see how their work affect the users and the business.
Next up, we will take a look at the disadvantages of using microservices.
For microservices to work together to solve a larger or more complex problem, they communicate with each via API calls over the network. This alone is complex enough to manage and implement. In addition, the e-commerce or finance domain typically feature workload that require transactional processing. Such workloads can be difficult to implement with microservices since APIs by default are stateless. To ensure the data integrity and consistency across the different system, additional workarounds or software components would have to be introduced.
Furthermore, different services would have different demand for their runtime environments. Different servers may have to be introduced, configured and maintained, which ultimately adds more points of failure into the whole system.
Lastly, there is also the complexity in terms of collaboration amongst the different stakeholders. Ideally, different parts of the microservices will have their respective owners. These developers would have to coordinate amongst themselves on the best approach to solve a problem, deploy and maintain the system. And when there is a miscommunication, the parts or maybe the whole of the application may not work properly, resulting in loss in productivity and cost.
Requires cultural changes
Traditional application built using the monolithic approach have a singular codebase that developers work on together. Organisations tend to split the project team based on their technical specialties (eg. Infrastructure, networking, UI/UX, backend). This can create a situation where the development team has no access to the production environment and lead to a disconnect between the developers and the customers.
On the other hand, microservices generally require the developers to have ownership of the full lifecycle of what they build. Organisations would need to think about and implement major changes in terms of the following:
- The size and the responsibilities of the team.
- The development and quality assurance process.
- The structure of the software and how it aligns to the business capabilities so that it can be broken down into small and autonomous services connected via APIs.
- How to deploy and maintain the services.
Depending on the organisation, this restructuring and cultural shift may impact the business operations and may cause productivity to drop as the people shift into a different mode of operating. Some employees may choose to leave if they are unable to adapt to such a change or unwilling to be responsible for the full lifecycle of an application.
When it comes to microservices, it is more expensive to run and maintain them over time because of the number of moving parts. In the event of a major software fault that brings down multiple services, multiple teams of developers/engineers would have to be involved to resolve issues, which translate to hundreds if not thousands of man-hours.
Furthermore, due to the complexity of microservices, it may take a longer time to restore the services back to operation when compared to the traditional monolithic applications. This could translate in monetary losses if the services are part of a on-demand product offered by a company or a realtime processing system.
More resources could also be required if there is a need to scale up the services by adding more virtual machine instances or servers in realtime to handle huge workload or sudden spikes in activities.
Pose security challenges
An application is split into multiple independent running services in a microservice architecture. In order for the different services to coordinate their action to support the business operation, they communicate with each other via APIs that are independent of the machine architecture and programming languages. This creates a large surface area for cybercriminals to disrupt the services and bring down a few services. This means that the security team will need to be hyper-vigilant about any possible interruption.
Organisations, in order to maintain their competitiveness and growth, would prefer to convert existing monolithic application into microservices. Different programming languages and frameworks may be used by different teams to build the services. As no programming languages or frameworks are completely safe and without vulnerability, each new introduction of language or framework to build new services and adding these services into the existing mix of microservices can increase instabilities and the number of security loopholes that can be exploited.
Furthermore, due to the distributed nature of microservices, traditional logs are not as effective when it comes to tracing what is going on with the application. In addition, there will also be more logs generated in a concurrent manner. This means there is a need to consolidate all the logs and correlate the events to generate a good picture of what is happening. Otherwise, there is a high probability that issues will be masked or covered up and prevent effective mitigation.
With this, we now know what is a microservice, the advantages and disadvantages. Next up, we will see what is not a microservice.
What is not a microservice
After reading through the advantages and disadvantages, maybe you came to the conclusion to microservices is easy to do and you feel confident about it. Maybe you think that you could just ask your software engineers to make individual function as a microservice for other parts of the software to use.
But that would be a huge mistake. The benefits of microservices will immediately be overwhelmed by the runtime overhead and operational complexity. Your project will suffer from over-engineering and timeline slip.
Justin Etheredge wrote an article called You’re not actually building microservices where he talks about the possible symptoms of a software system that is not built using microservices.
- Any changes to one microservice often require changes to others.
- Deploying one microservice requires other microservices to be deployed at the same time
- Excessive communication between microservices
- Sharing of the same datastore by multiple microservices
- Microservices share a same code or models
However, even if an application shows one of the above symptoms, it could still remain as a microservice because there will always be exceptional cases. But alarm bells should go off if a service or application displays more than one of the above symptoms. That could mean it is not a true microservice.
So when do you use it?
Even though microservice architecture is the trendy thing to do now, it is generally advisable not to do it for a new software project or a proof of concept due to the complexity, cost and cultural changes needed. It may even slow down the development process.
But that is not to say to we should stay away from microservices. Rather, the only time to consider converting an application into using microservice architecture is when the following criteria are met:
- The software has grown too big to be managed as a monolith as described by Martin Fowler in his article.
- The organisation has the resources in place and is ready to go onboard with it.
- The software needs to adapt quickly to market needs.
- Parts of the application needs to be extremely efficient.
Jake Lumetta wrote an article titled Monolith vs microservices: which architecture is right for your team? that reinforced the above points 2-4.
In the same article, Jake also list down the scenarios that are not suitable for microservices:
- Your team is at founding stage and has only a few members.
- You are building an unproven product or proof of concept.
- You have no microservice experience.