Mindset
There’s no silver bullet for software engineering.
Keep what is good for the business from various methodologies, avoid or troubleshoot the bad is my approach to tackle problems.
Why Microservices? Why decompose our monolithic system into microservices?
Technology is to enable business.
Here are the key factor and benefits that microservices bring to businesses:
- Ultimate goal: high cohesion, loose coupling, and these are the basement to support the following benefits.
- Agile software development and testing with clear team responsibility and isolated dependencies, which in result fasten the time to market providing first-mover advantage to the business
- Locality benefit(Principle of locality) and better resource(CPU, Memory, and etc) usage because when the application run, it doesn’t has to load unnecessary resource, such as cache, and execute useless schedule tasks.
- Dynamic scaling with cloud and containerisation technologies to solve issues like heavy traffic in high concurrent scenario.
- Better communication with ubiquitous language.
What are the potential problems regarding microservices?
- Performance issue, RPC(Remote procedure call) brings extra latency to process a request.
- Microservice governance difficulty, data consistency, link tracking and monitoring are tip.
- Greater complexity compared to monolithic systems in terms of development. Engineers will face those distributed systems design challenges such as distributed transaction, distributed ID, distributed locks, data consistency, and etc.
How to optimise the advantages and minimise the disadvantages?
- According the business requirements, unless having the necessary to have the advantages like those mentioned above, don’t decompose to microservices;
- Having clear bounded context;
- Benchmark performance
- Should limit to 3 to 5 microservices to process a request;
- When having performance issue, figure out which service is the bottleneck of the process link, applying caching, allowing certain level of data redundancy to reduce the latency or shorten the link.
- If the point 2 cannot solve the performance issue, then merging certain microservices should be taken into consideration.
Sample approaches:

DDD issues
While DDD has many benefits over a long term software development, it has certain severe issues that hinders its application on software development.
Here are some of the typical examples:
- No mature and rich community support framework to implement this methodology till now.
- Decomposition of modules is hard.
- The aggregate root could be cumbersome. Within the domain, there could be duplicate methods. It is hard to make an abstract parent class as some of the methods has no direct relation with certain children classes. We might end up need experts with in-depth experience to extract those common methods to a common module.
Despite these problems, what we can take away from DDD?
The concept of Bounded Context
A bounded context is simply the boundary within a domain where a particular domain model applies.
25 Feb 2019 Domain analysis for microservices – Azure Architecture
In simple language, it is the boundary that a service/business can self-sufficient to achieve specific purpose with its own rules, procedures, process, and etc.
We can apply the bounded context concept to decompose our monolithic system into different domains. Sample event storming approach will be provided in later section of this artcile.
Types of Domain
Core domain: must have things, the things that all your strategic resources must invest in.
Support Subdomain: could have things, less important things that can be outsourced.
Generic Subdomain: things that everybody want. For example, authentication service that most if not all services of your system will need.
Conventional strategies to divide into subdomains
- bounded by business responsibility(kinda like SOA);
- bounded by feature, more about microservices with higher granularity compared the first one;
- bounded by organisational structure;
- the two-pizza rule
You can have a boundary large like a department store. You can also make it small like an exquisite boutique only selling specific type of goods. It really depends on what works well for your business.
Again, technology is to enable business.
The difference between hallucination and vision here is just two words, business needs.
Find the boundary with event storming
Identify domain events with 3 key factors:
- having business benefits
- in the past tense
- ordered by time
The Process

Strangler Vine Approach
A strangler vine grows around a tree to reach the sunlight above the forest canopy. Eventually, the host tree dies leaving a tree-shape vine.

Basically, with the bounded context, decompose certain part of the monolithic system into microservice. At the beginning, the extracted microservice can share db with the original service, but eventually it will has its own db and RPC to original service for some API invocation.
You might need to write glue code to assist the communication between the new microservice and the old service.
Where to start?
- Some modules that are simple to extract.
- Some modules that are frequent changed.
- Some modules that have the most business benefits.
- Some modules that implemented with heterogeneous technologies.
- Some modules that in your high priority.
What Patterns can apply?
Integration Patterns
- API Gateway
- Aggregator
- Proxy
- Chained
- Branch
- Client-side UI Composition Pattern
Cross-Cutting Patterns
- Service Discovery Pattern(Eureka, ZK)
- Circuit-Breaker(Hystrix)
- Client-side load balancing(Ribbon, Spring Cloud LB)
- External Configuration(Apache Apollo, Spring Cloud Config with RabbitMQ)
Database Patterns
- Database per service
- Shared Database per Service
- Saga
Decomposition Patterns
We’ve talked about these in previous sections.
- Strangler Pattern
- Decomposition by business capability
- Decompose by subdomain(DDD)
Observability Patterns
- Log Aggregation
- Distributed Trancing(Apache SkyWalking, Slueth + ZipKin)
- Health Check(Actuator)
- Metrics(SpringBoot Admin)
Distributed System Design
Distributed Transaction
- 2PC, 3PC, TCC
- Transaction Outbox Pattern(It’s local transaction table + MQ)
- https://masteranyfield.com/2021/07/26/dealing-distributed-transactions-with-2pc-3pc-local-transaction-table-with-mqs/ I’ve talked this pattern at the end of this post.
Distributed Lock
- Redis + MySQL Optimistic Lock
- RedLock
- ZK
Distributed ID
- UUID(Not storage friendly, not suitable for many scenarios, security issues, not recommend)
- MySQL Auto Increment ID(Poor approach, low performance, single node failure, not recommend)
- Redis (not reliable enough, AOF reduces performance, master-slave asynchronous synchronisation would result in data loss)
- ZK + Redis (Recommend, ZK for consistency, decent performance with data consistency)
- ZK with SnowFlake (Recommend)
I will go through how these techs works and their implementation details when I have time in the future.