Nowaday we are familiar with web framework such as Diango, Ruby on Rails, Spring etc. They are using MVC (Model-View-Controller) pattern. That inspired developers a lot and speed up our development, helping us more happier while coding with well-designed source code. We put all business rules into the same codebase, are called monoliths or monolithic application.
For years, we have been working on monoliths and we found a ton of difficulties:
- Maintenance: when the team grew up to many developer, we encounter problem of merging code.
- Implementation: new features are complex time by time and take longer time to get them done. I found that the new features actually are not complex, even simple but difficulties occur when we try to combine them with legacy code.
- Scalability: We put them all together so let's think of Big Ball of Mud. There are a lot of connections time by time.
- Deployment: Impacts from deployment. We have to wait for someone to deploy and we have to merge code and for sure we have to test again. If there is just small team, no problem. But if that is a big team. We have to do those things over and over again. It takes so much time and takes risks as well.
Thus, In order to solve above problem, we approach Microservices architecture. It would benefit:
- Isolating business domain for each microservice: it is good for management and maintenance.
- Independent deployment: Good for big team.
- It leads to Independence between teams as well. Imagine each team manages specific number of microservices. A team can work on multiple Microservices projects.
- Implementation of isolation.
- Scalability: Increasing number of microservices. Scaling each microservices etc.
Domain Driven Design
As we know that Microservices including micro-services. So we encounter a challenge that how we divide services. DDD is as important as Naming a service. When we think of a service we do know what it does.
Single Responsibility Principle
The key is "micro". It can not obviously be large. It needs a boundary. Applying S in SOLID we make it easily to maintain.
Each service needs to be independent completely.
Upgrade Monoliths to Mircroservices
Despite this article is about introduction of Mircoservices but it would be more clear if we have big picture between monoliths and microservices through some points at upgrading time.
- Strong boundary of microservices domain: SRP, maintenance, easy to understand WHAT.
- Do not share libraries between services: it leads to high coupling and deployment issues.
- Do not allow client-service relationship:
- each service must be independent. Only ask other service for information, do not wait for the answer.
- asynchrony is the key.
- Deploy in separate containers: It means physical containers, not sharing memory. Group of services can be in same physical container but it takes risks. This is recommendation.
Above picture is scale cube presented by THE ART OF SCALABILITY from Martin L. Abbott and Michael T. Fisher. I will introduce it more details in next article but now let's go through some points.
There are three dimensions to scale: x-axis, y-axis and z-axis.
- The x-axis: horizontal scalability. Cloning same application server replicated n times (database and caches will be required). Main idea here is increasing number of physical servers.
- The y-axis: Divide routes by balancer to exact service which handle specific domain.
- The z-axis: The scale is based on data subsets. For example, we replicate UsersSevice. Thus, we have on UsersService for users from Vietnam. Another UsersService for Singaporean etc. In addition, one service serves username with starting letter from A..H. Another serves users these ones from I..Z. Data subset is the key.
We can see that the Balancer is very important in scale. Scale can not work without it in Microservices. Moreover, we can combine x-axis, y-axis and z-axis so that we will have many balancers. It is easy to find that if a App crashed, balancer are able to redirect requests to replicated servers, making sure the availability dimension.
Light weight communication
The are two methods of communication: Synchronous and Asynchronous. The is no the best, only the better. So it depends. For direct and sequential system, we use sync would be better. In case no need instant response, async is better. RabbitMQ, ActiveMQ, ZeroMQ, Kafka and Redis are good choices. The is no single solution for everything in software development. So in Microservices we can use both two types of communication. However, remember that each service is independent. Thus, if we use sync, we might use it in same service - request/respond instantly.
Documentation of communication
When we come to Microservices, Document is very important among team. The Swagger API is a good alternative solution.
Caching at client level
Thanks for reading.