This content originally appeared on Level Up Coding - Medium and was authored by Abhishek Kapoor
Microservices provide a lot of advantages over monolith when implemented correctly. Many Organizations want to change their monolith application code to microservices code. It turns out, migrating to microservices isn’t that easy. The first question you should ask is, do you really need microservices. Many problems of the monolith can be fixed easily by using modular monolith architecture. Once you have become sure that you want microservice, you have to create a plan to convert monolith into microservices. There are some patterns that can help you to create the required plan.
Before we go into actual Patterns to divide a monolith, let’s talk about what shouldn’t be done.
Don’t do Big Bang ReWrite
Big Bang Rewrite, as the name suggests, we have to rewrite the entire monolith’s code in microservices and deploy it in production all at once. Once Martin Fowler rightly said:
The only thing a Big Bang rewrite guarantees is a Big Bang!
Big bang Rewrites are always dangerous. Big bang rewrites take a lot of time to develop as you have to code everything which is in a monolith application. Also, during the development of microservices architecture, you have to freeze further development in your monolith, as, every change done in monolith has to be done in microservice also. For most companies, freezing application development can be dangerous as they have to adapt according to the change in the business environment.
It's always better for an organization to gradually move to microservices from the monolith. Some design patterns are available which can help you to gradually move to microservice architecture from monolith.
Strangler Fig
Strangler fig is a pattern which was purposed by Martin Fowler. Strangler fig is inspired by actual figs, which start small on top branches of the host tree. Fig’s root starts growing towards the ground. Slowly its roots will reach the ground and it will keep growing, even killing the host tree in the process. Likewise in the software world, we will build microservices around a single monolith application according to this pattern. We will keep adding more microservices incrementally in the system, eventually replacing the entire monolith system one day.
In Strangler Fig we create new services around the edges of the existing monolith. What do I mean by edges of monolith? let's understand by example.
In Figure 1, you can see we have one monolith application. Now, in the above diagram, modules Product inventory, Order Management, and Billing Management are at the edge of the application. Notification Management has multiple inbound calls from within the application. Therefore, we can’t redirect all inbound calls to Notification Management from the outside application. We have another pattern to move Notification Management to microservices which we will discuss later.
Suppose we wanted to migrate Billing Management to microservice. We can use the below steps to migrate monolithic to microservice.
- Insert Proxy: Unless you already have a proxy in place, we need to deploy another HTTP proxy. In Step 1, we have an HTTP proxy that will redirect all calls directly to the monolithic application. By introducing HTTP proxy you can also know if any additional hope over the network can delay API calls. If the delay is significant, then you have to stop migration and first improve your network before continuing further.
- Deploy Microservice: In step 2, you will just deploy microservice in production. There won't be any live traffic on our microservice. In step 2 we will just test our microservice if it is working fine.
- Redirect Traffic: In step 3, we will redirect actual traffic to our new microservice from HTTP proxy. If there is an issue we can easily roll back by changing the HTTP proxy.
All steps are also shown in Figure 2.
Branch by Abstraction
When you have to extract a module on which other modules depend, then branch by abstraction pattern can be useful. Suppose in the previous example we wanted to convert notification management into microservice. In that case, we will be using branch by Abstraction. We need to do the below steps to extract a module.
- Create abstraction. You need to create abstraction around the module you are going to replace.
- Change clients of existing functionality to use new abstraction: you need to refactor old code so that the old implementation, implements abstraction created at step 1.
- Create new Implementation. You need to create a new microservice implementation for functionality and deploy it in production and run some tests.
- Switch Implementation. Once you have run some tests and you have some confidence then you can switch to a new code.
- Cleanup. Once your microservice is up and running then it is better to clean the old code base and remove old modules. You can also remove abstraction if you want to. In many cases, the Abstraction which you created earlier would have just improved your codebase, in those cases it totally fine to keep it.
TO better understand the entire process please refer to figure 3.
Branch of Abstraction can be used in a lot of places. Its always recommended using Strangler Fig instead of Branch of Abstraction wherever it is possible. Once you are sure you cannot replace some part of the monolith to microservice with Stranger Fig as it is well within your microservice then Branch of Abstraction should be considered.
Parallel run
No matter how much you test, there are still possibilities of bugs. When you are migrating a critical system then you just cannot leave anything for luck. In such a scenario parallel run pattern can be helpful. In this pattern, we will deploy our newly developed microservice along with monolith in production. We will let data flow from both systems. The Monolith system would be the only source of truth initially. We will compare the results of the newly developed microservice with that of the monolith. If we found any mismatch we will fix it in our microservice application. After some time, when we have enough confidence in our new microservice system we can just decommission functionality from the monolith and make microservice the only source of truth.
In the previous example, let’s say we want to migrate billing management from monolith to microservice. In this case, we will develop a microservice and send the same traffic to our new microservice. At end of the day, we can have any batch job to compare if bills generated by both the legacy system and the new system are the same. Once we will have confidence we can discontinue the billing system from the monolith. We also have some open-source libraries like Github's scientist library which will help you to implement this pattern better.
The patterns which have gone through till here were useful when your functionality was already present in the monolith. Let's imagine you have to add new functionality. Maybe let’s say you want to email discount coupons to users for the next purchase after every successful purchase. It’s straightforward, you can just add new code from the order module of the monolith to call the newly created discount microservice. But if you didn’t have the code? Say you were using the solution from another vendor or were using some SAAS, then can you still achieve it. The next two patterns which we are going to see are just tailor-made for this situation.
Decorating Collaborator
This pattern is inspired from one of the pattern which we already know and love, The decorator pattern. In this case, like a strangler pattern, we have to introduce a proxy. We will let calls go through a proxy to the monolith and based on the response from the monolith, proxy will call our newly created microservice.
Figure 5, represents the working of the decorator Collaborator. This pattern should only be used when all data required by microservice is already present in the request or response. In case data is not present then our newly created microservice will have to connect with the database of the monolith. It will couple our new microservice with the database of the monolith which is never a good idea.
Change Data Capture Pattern
In this pattern, we will react to changes happening in the database. Let's say, we want to create a loyalty card for every customer created in our system. In this case, we can listen to the change in the customer table. Once we detect a new customer has created n the customer table we can invoke Loyalty microservice. Loyalty microservice then can issue a loyalty card to customers and send an email to them with details. There are various ways that you can utilize to listen to the change in the database. You can either use triggers or you can use transaction logs of the database. One can also write a process that can trigger after few minutes and check for any change in the database.
Conclusion
Microservices offer many advantages when implemented correctly. Converting your monolith application to microservice is not going to happen in a day or week. One should also remember converting to microservice is not a race, but a slow marathon. It requires a lot of patience and good architectural decisions have to be made.
In this article, we discussed some patterns you can use. Most of the time you will have to choose multiple patterns to fully convert your monolith application to microservice. In end, I will just suggest, before migrating to microservice take your time to figure out the strategy you will be using, it is going to pay off in end.
References:
Patterns to know before migrating your monolith to microservices was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Abhishek Kapoor
Abhishek Kapoor | Sciencx (2021-05-04T12:59:49+00:00) Patterns to know before migrating your monolith to microservices. Retrieved from https://www.scien.cx/2021/05/04/patterns-to-know-before-migrating-your-monolith-to-microservices/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.