Web application to Microservices (Do we use it or not?)

Source: https://www.sam-solutions.com/

🔰 Microservices is the most trending topic in the last few years. In 2013 with Martin Fowler's concept about microservices and after several discussions about microservices, people started to think about some new architectural patterns for web applications.

🔰 That’s how microservices came into the picture. Now people are thinking about whether we need to go for this or not.

🔰 To understand whether we should go for microservices or not, we should compare microservice with the architecture we have now and what goal we are trying to achieve.

🔰 So, let’s discuss how we can migrate from web applications to microservices with advantages and disadvantages of current architecture and microservice architecture.

Monolithic applications

🔰 Before microservices become famous, monolithic architecture (traditional approach) was the architecture used to build applications.

🔰 In monolithic architecture there one single executable file for the entire application. It always doesn’t have to be an executable file. It could be a WAR file, ER file or some other archive. So basically, your entire application is packed into one file.

Monolithic architecture (Source: https://www.n-ix.com/)
Monolithic architecture of an e-commerce system

🔰 We already know that in monolithic architecture everything is in one application. Assume you have an e-commerce application.

This application has

  • User interfaces.
  • Business layer with business logic.
  • User registration.
  • Seller registration process.
  • Billing process.
  • Order shipping.

🔰 In monolithic architecture, all the above are put together and shipped as one file.

Drawbacks of monolithic architecture 😪

1. Everything in one application

🔰 So far everything is good. But what happens if the client requested a system modification. This could be a

  • Simple UI change.
  • Change the date format.
  • Modification in business logic.

🔰 Now, this is where things are getting hard. Because your whole application is a single unit and even if you make a small change you have to ship the whole application.

🔰 Not only that you have to test (Ex: Regression testing, performance testing) the entire application. Also, sometimes you will have to take down your whole application (send it offline) to update it to a new version. (Have to redeploy the whole application even if it’s just a minor system modification).

2. Have to maintain a huge codebase

🔰 Sometimes around 50–200 engineers are needed to develop a single large-scale application. So, at the end of development, there will be one very large codebase. The problem is maintaining this huge codebase. Because it’s a very large codebase and not everyone knows everything about the system.

🔰 So, when an issue occurred in the system it won’t be easy to debug the system. Because the flow of the system is very complex and no one knows everything about the system.

3. Hard deployment process

🔰 The deployment process is hard. You have to make sure everything (ex: dependencies, modules) are offline and traffic is rerouted.

🔰 Sometimes when there is a deployment of a new update or a new installation, the entire team might have to work overnight to make sure the application is working fine.

Now that we have been talking about disadvantages, let's look into the advantages.

Advantages of monolithic architecture 😃

1. Easy to test

If the application uses monolithic architecture, it's only one application (even though it's large scale). So performing integration testing is very easy

2. Easy to monitor

Since it’s a single application.

Anyway, as a solution to the above-mentioned problems, we have microservices…!

Microservices

In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.

- James Lewis and Martin Fowler (2014)

🔰 Some would say microservice is of SOA 2.0 (Service Oriented Architecture) or microservice is another era of the service-oriented architecture. This is because microservices actually carry some useful features of SOA.

🔰 There is no exact definition for microservices. Because microservices are a practice, an architectural view.

🔰 So Martin Fowler tried to explain this in a way everyone can understand in his book. You can also check out his website as well.

🔰 Martin Fowler pointed out several key factors and explained that if an application behaves according to these points it can be called microservices.

Qualities of microservices

Let’s try to understand microservices step by step.

✨ Microservices should have has a dedicated purpose of living. (you could say its domain driven development). It also should have a well-defined scope.

✨ We should maintain decentralized control as much as possible.

✨ Should be able to run its own process. Should not depend on someone else (ex: own web container).

✨ Communicate with other services via lightweight communication mechanisms.

Microservices can communicate using some lightweight mechanisms (Mostly its HTTP but it doesn’t have to be limited to HTTP).

✨ Scale and deploy as independent services.

Microservices should be able to scale and deploy independently.

If you go through “The Art of Scalability” it explains this. (The Art of Scalability: Scalable Web Architecture, Processes, and Organizations for the Modern Enterprise by Martin L. Abbott, Michael T. Fisher).

Source: “The Art of Scalability” book

There are 3 axes X, Y and Z

🔰 The application should be able to scale through the X-axis (if one instance is not enough you should be able to spawn other instances and keep going. This could be more clusters or more data centres whatever it is application should be able to scale out)

🔰 Through Z-axis application should be able to be sharding. The application should be able to geographically wise spread out the traffic (ex: European users are directed to European servers and Asian users to Asian servers).

🔰 Through Y-axis functionally decomposition should be possible.

Someone could say “my system is a very large-scale application; I can’t even imagine migrating this to microservices”.

Let’s go back to our e-commerce application again. All the services like user registration, seller registration process, the billing process, Order shipping are in the same application.

If you want to migrate this monolithic e-commerce system to a microservices application, first you have to think above services as separate services (independent).

Common misunderstanding

We don’t break down systems validation, data conversion, protocol conversion (if there is) in to separate services. This is a wrong approach.

Because when microservice architecture is used we break our application into separate services and they take some time to communicate with each other. So, your application should have right balance.

Anyway, back to our e-commerce application. Now you have separated services in the application. When you are doing this, you have to keep one thing in mind.

🔰 The seller module has a seller. Assume that the shipping module also has a seller. Now when the seller appears in the shipping module it’s a different perspective (a different domain). Thank you have to keep in your mind. This is also the reason domain-driven development is a feature of microservices.

🔰 So, when you implement a service, you should think and evaluate what is your domain, your objective and where you go with that domain.

🔰 For example, assume that our shipping module is the most demanding service and the seller registration is the least demanding service. When there’s a high demand for shipping service, we can spawn out a new shipping service to balance the load.

🔰 If the demand for shipping goes higher and higher, we can spawn more instances and balance the load. Also, when the traffic is low, we can take down the extra instances Meanwhile seller registration might have only one instance due to the low demand.

🔰 But when monolithic architecture is used, and when you want to scale out you have to spawn out new instances from the whole application. Even though you want to spawn out only the shipping service, you get an instance of the whole application and that instance has UI, seller service, billing service (everything of the whole application).

🔰 This scale-out on demand (elastic spawning) is definitely a cost-effective method. So that explains function decomposition and how individually scalable.

✨ Microservices should be able to be developed by a small team

🔰 The size of the team is generally defined as “Two Pizza team”, which means the whole team can be fed by two large pizzas 🍕. (But this could be different to the team members appetite, right?). So, the headcount would be 8 -12.

With considering all above, we could say the baseline for microservices is “do only one thing, but do it damn well”.

Monoliths and Microservices (Source: https://martinfowler.com/)

Developing microservices application

Microservices vs Monolithic architecture (Source:https://xbsoftware.com/)

🌟 Design

When it comes to the design it’s very important you have to consider domain driven design. You have to make sure each of your services doesn’t depend on other factors. Your service should be able to be removed from the system at any given time and plug into the system at any given time.

However, that doesn’t mean the system should be able to run without the particular service. In order to deploy Your service, you should not have any hard dependency on other services. There shouldn’t be dependencies like service A can be deployed only if service B is deployed.

🌟 Service resilience and fault tolerance

A consequence of having multiple services is that one of them could fail. Assume you have service A, which invokes service B. What happens if service B doesn’t work (ex: time out, service fail) when service A invoked it. Now the service A should be able to handle this kind of situations.

There are several ways to handle such situations. You can have a failover mechanism, a proxy or a circuit breaker pattern.

🌟 Do not try to reinvent the wheel

There are various frameworks out there that support microservice development. (Frameworks for deployment ex: API gateways, governors registry). Instead of trying to invent such things yourself, it’s better to go with such existing tools if they match your requirement.

🌟 Restructure the team

Your team is responsible for one separate service. So, your team should have someone with knowledge of UI (User interfaces), DB(Database), QA(Quality assurance), Service development (ex: Java). You should have a full stack team that knows every area.

One of the features of microservices is that team should have visibility from consumer to backend. This could be a bit challenging if you used to have a separate team for each domain (ex: team for DB, team for QA)

“You build it. You own it”

The usual practice is we build the system and give it to the support team. So, it’s all their responsibility. But it's not the same with microservices. With microservices “Your build it. You own it”. You have to make sure you build proper, stable, strong service. Because responsibilities are distributed among the team.

Pros and cons of microservices

Pros 😃

✅ If any issue occurred in the system during production, the team knows what happened. (The whole team is aware of the entire service).

✅ Even though the whole application is large scale and complex its services are isolated. So, you don’t have to go through 1 million, 2 million code lines. You only want to know about your service.

✅ Easy to scalable (we discussed this above).

✅ In case your framework is outdated or you want to change the language it's very easy to migrate to a different language or a framework. Because your service doesn’t have any dependency on other services.

Cons 😫

❎ Normally (monolithic application) we have one central location for dependency management (one dependency management system that takes care of dependences of the whole system). But we can’t do the same here. We have distributed all the complexity of the whole application among services.

Hard to monitor the application. (it’s not a single application anymore. Have to monitor multiple services).

Not easy to test: each service is isolated.

Versioning and deployment.

If you change the version of a single service, consumers of that service might be affected.

Have to make sure all services are up and running. In monolith when you start your application all services will run. But in microservices, you have to make sure all the services are running to make sure the application works.

Summary

Source: https://blog.knoldus.com/

💢 If you have a monolithic application it's easy to monitor but it would be hard to scale. But in microservice architecture, it's easy to scale since services are isolated and independent.

💢 Services of microservice application should have dedicated goals, should be able to independently scale, developed and maintained by a separate team by any desired language.

💢 The team has a responsibility for the service and since the team headcount is 8 -12, communication among the team is easy. (Teams should be a full stack team).

So that’s all for this article. I hope you learned something new. If you have any ideas, thoughts please comment below. Thank you.

Associate Software Engineer at Virtusa