Setup your architecture for the future with microservices
Microservices architecture is an architectural design choice. It structures an application into a collection of fine-grained microservices, which are responsible for specific parts of the application. Many digitally focused organizations have adopted a microservices architecture as it gives them increased freedom and performance with respect to software development: Freedom to make decisions, react to necessary changes, or adopt and embrace new technologies. Performance, as it allows to deliver value to customers faster.
In order to build a microservices architecture, one needs to have microservices first. But what are microservices? In its essence, microservices are small, autonom software applications that focus on doing one thing well. From a software application development perspective, they are nothing special. It is the school of thought that defines microservices - shaping their resulting scope and characteristics.
Thinking in microservices fights against the challenges and problems experienced by many organizations when developing monolithic applications. Even with good development practices in place, large monolithic codebases can make it extremely difficult to actively drive further development, incorporate new features and adapt to changes. Where do new features have to be implemented? Does similar functionality already exist? Which parts of the application are coupled and need changes? Development might become increasingly difficult and complex that large monolithic applications stagnate or even freeze in progress.
Microservices are small independent services that have service boundaries aligned with respect to business boundaries. These explicit boundaries keep them from growing out of their scope. Microservices are autonomous services which can be seen as independent entities. They can be developed and deployed independently from each other. This results in many and diverse benefits, which have their foundation in distributed systems. Key benefits include:
Every microservices can potentially use a different technology. Thus, it is possible to pick the right tool for each job, adopt or try technologies more quickly, or optimize services as required.
Performance issues can more easily be identified and resolved, faults are better isolated and the risk of application downtime is reduced.
Services can be scaled independently, which makes it possible to respond to changes in demand specific to certain parts of your application.
Microservices are focused on one specific task within the application. This makes it easier for developers to familiarize themselves with services, understand them more quickly and contribute with code changes. Furthermore, tasks can be divided among development teams. Both decrease the time needed for changes, features or bug fixes to reach your customers.
Now we have seen and understood the benefits of microservices and are keen to get started. But how do we structure software applications into small, autonomous services? What do we have to consider? Two key aspects of what makes a good microservice are loose coupling and high cohesion - two aspects which are highly related to the overall architecture we are aiming for.
Loose coupling means that changes within one service do not require other services to be changed, too. Thus a service should know as little as possible about services it communicates with, or only as much as required. We do not want to have chatty communication between services as it increases their coupling. High cohesion allows us to condense behavior within one service - and one service only. Changed application behavior should result in changes in one microservice. Again we do not want to be forced to change more than one service at a time to deliver changes in application behavior.
To achieve loose coupling and high cohesion, it is important to get the service boundaries right. Easier said than done. Service boundaries are dependent on the overall structure, service offering and goal of an organization. Boundaries of a microservice have to respect and consider existing services. Moreover, boundaries will shift, services will be replaced, splitted or completely removed. Change is inevitable. Not every microservice boundary will turn out to be perfect. With microservices, however, you have the flexibility to react and adopt. We at Blueshoe can support you with our knowledge and experience on getting started with microservices.
As you surely understand at this point, a single microservice does not make an architecture and most often it is not very useful in isolation anyway. After building a microservice, it is necessary to integrate it into an existing architecture to make use of it. The term microservices architecture thus refers to a system architecture which is composed of many integrated microservices.
Getting the integration of microservices right is an important point that should be paid special attention to. It is essential to allow for autonomy and independence between services. Wrongly implemented, it can crush the benefits of microservices at its core, making them inflexible and coupled. There are different technologies that can be used for integration, such as REST, GraphQL, Protocol Buffers and more. The best technology choice, however, depends on the overall architecture and application. Generally speaking, it is advisable to keep APIs used for integration technology-agnostic, avoid breaking changes, make them simple to use for consumers and hide internal implementation details. Furthermore, a shared database should be avoided and the communication should preferably be choreographed instead of orchestrated.
After recognizing the benefits of a microservices architecture, an organization might still struggle to make the decision to adapt it. This hesitance can be caused by the following questions:
These are all valid questions and the answer highly depends on the organization's structure and technical skill. When starting to introduce microservices into an organization without prior knowledge or experience, it might be advisable to take it step by step. You have to analyze the current monolithic architecture and start identifying potential service boundaries as described above, which separate your codebase into independent, decoupled parts.
After defining potential microservices, you should take one step back and ask yourself: What is the value I want to gain out of splitting the monolith? Surely no-one should split a working monolith without reason. Identify and anticipate potential services that are expected to change in the near future. Divide the ownership of services according to your team structure. Consider security critical aspects or technology considerations.
It is important to transfer the key benefits of microservices as mentioned above onto potential services. What do you want to gain? By answering this question the future value of splitting out the identified microservice from the monolith should become clear! Start with the microservice that makes the most sense with respect to value and complexity. Gain experience and split/replace your existing monolith step by step.
Handling deployment, testing, monitoring and security of microservices within a microservices architecture can seem highly complex and intimidating. Instead of one software application, it is now required to manage many different microservices independently. While there are certain aspects specific to microservices, the overall approach can largely be transferred from software development in general.
In order to handle the increased amount of services, however, it is greatly advised to have separate repositories pre microservice and automate the whole process as far as possible - preferable completely. Every microservice should have a functional and well planned continuous integration and continuous delivery (CICD) pipeline. Automation is your friend. Automate everything!
Setting up our customer projects according to the cloud-native approach helps us to develop complex systems quickly and efficiently and to implement short, efficient release cycles. The following projects are a small excerpt from our past cloudnative projects.
In the second edition of our podcast "Tools for the Craft - Navigating the Kubernetes ecosystem" Michael and Robert talk about the various options developers have for remote K8s development and will show some real life examples.
More editions of our podcast can be found here: