Microservices Architecture: Breaking the Monolith
We will discuss how you can break a monolithic application into smaller pieces that make up a modular system, and discuss migration to the cloud.
This article summarizes the Breaking Monolith webinar presented by By Daniel Gutierrez Saavedra, senior software engineer of the company Zartis… You can watch the full text of the webinar, which also includes a Q&A session, below!
Are you working with monolithic systems and legacy applications? Are you looking for ways to modernize your architecture and move to microservices? In this article, we will discuss how you can break a monolithic application into smaller pieces that form a modular system.
Why choose microservices
Microservices are developed using business-oriented APIs to encapsulate core business capabilities. Loose coupling helps to eliminate or minimize dependencies between services and their consumers.
Among other things, they are:
After all, microservices architecture is much easier to test and deploy. If we add a DevOps approach to the equation, where we have very small pieces of code that can be tested and deployed in small chunks, the benefits cannot be overlooked.
It is important to recognize here that the architecture of microservices does come with some challenges. There are several additional levels of complexity as there will be many moving parts in the system and testing microservices can be difficult.
Some of the main issues to consider are:
Additional difficulty levels.
If your software doesn’t change frequently, it might not fix anything.
Purchasing new products requires additional costs.
Once you go to the cloud, it allows you to do additional activities like logging, additional security measures, etc. Your team will need to independently learn how to use these tools.
Destruction of the monolith
An effective way to migrate a system to a microservices architecture is to start by defining the core services and then refactoring and decoupling them. Let’s take a closer look at how you can make these changes and take a look at the best options for storing your application in the cloud.
Step 1: Define Basic Services
It is a good idea to start your migration by identifying the critical services that can be the ones that generate the most revenue for your business or are often used by your customer base. These services will be the most difficult to separate from the monolith.
The criticality of your service is determined only by you. But the first thing you should do when moving to microservices is to identify them. When it comes time to cut the elements, it’s best to do it. horizontally – just imagine it in terms of layers; you have a business layer, presentation layer, data layer, etc. Slicing vertically would mean trying to separate functionality that spans the full range of layers in your applications, which can lead to boilerplate and duplicate business logic.
Take Domain-Driven Design (DDD) as an example. In a microservice-oriented system, perhaps our domain is very large, which can span many microservices, and they can function as subdomains. So it is a very similar approach to system design, and it is perfectly compatible with things like DDD, BDD, etc.
Step 2: splitting and refactoring
So we saw how we can decouple everything, but now how do we decouple services from everything else and refactor them to become a set of microservices?
The first thing to know is that the less communication, the better the relationship. It is very easy and tempting to create many services that are convenient to test individually, but your overall system will become complex and confusing. This makes it difficult to track down when a problem occurs, as there is a lot of confusion and it can be difficult to pinpoint where the root of the problem lies.
Another important point is the enqueue of events. We’ve been told many times that we can’t split them into separate services because it’s perfectly in sync for events that happen in the next stages. This is usually not the case. With the queuing and topic messaging systems that exist today, there are many ways to get out of sync. It is true that you are adding an extra layer that can introduce some latency problems, but in the long run, being able to break all of the synchronicity will probably improve your result.
Step 3: API and cloud
Now that we’ve done all the slicing and stripping our code, where can we put it all? Into the cloud!
Today we have many solutions, and this is just a small part of what the cloud provides us with.
To name a few of the more common ones, Google Cloud (GCP), Microsoft Azure and AWS are the three main contenders, but there are many other vendors as well. These solutions usually provide an out-of-the-box microservices architecture where you only need to do a few finishing touches and do a little bit of training to get it up and running.
In addition, there are solutions that are needed locally because you don’t want to host your services in the cloud. For example, using Spring Cloud services, you can use your own servers and ideally mimic public cloud structures.
How much might a cloud migration to microservices cost?
It’s very easy to keep building microservices in the cloud, but if you don’t have a clear plan, you might lose control of your project budget. If you want to get an estimate of how much you can spend on cloud services, there are several ways to do this.
Using the calculators provided by most cloud services, which are very detailed, you can get a good estimate, but for that you need to have a very clear idea of what your customer base is, the volume of transactions, the amount of data, code, etc. If you have all these parameters, then you can reliably estimate what your costs in the cloud will be.
Unfortunately, this method of calculation is not suitable for local providers such as Spring Cloud services, which incur various costs associated with having a local server.
Common migration strategies
Let’s take a look at the most typical migration strategies in existence today to help you get a clearer idea of the path you might want to take.
One way to migrate is to use the strangler pattern – in case your application is very large. This way, you can isolate the most important services in the microservices architecture.
In the case below, it was decided to pull the entire client side of the application into the microservices architecture and leave the administrative side in a monolith, which is fine. They significantly expanded their code and were able to do it without stopping development. But that doesn’t have to be the final state of the application. Ideally, everything should be on the right side of the image. As you can see, there is a DBF in there, i.e. a DB (database) for each service. This is not a requirement, but it helps.
Another way to accomplish the migration is to use a parallel development approach. This is more suitable for small projects or projects that are not very advanced in development. This way you can develop both monolithic architecture and microservices architecture in parallel.
The main pitfall of this approach is that it usually doubles the amount of maintenance and code duplication, but it will end up on the right side of the screen, and if you want to reduce risks, this method can help a lot.
When we are in the process of migrating, it is important not to get ahead of ourselves and try to make changes in parallel or design them ahead of time.
Imagine you are working on a parallel migration and decide to migrate alongside development; if new functionality or feature comes along, you have to duplicate that code and do the work twice. If you try to plan your migration ahead of time while making changes to your main application, you have a hard time avoiding complications.
Translation of the article prepared as part of the course “Microservice Architecture”… If you are interested in learning more about the course, come to Open Day online, where the teacher will tell you about the format and training program.