Moving from monolithic applications into microservices is current trend in software design. Let’s identify some pros and cons of both architectures and challenges one may face during the system transformation.
The drivers that makes decision to split one system into microservices are:
- Monolith codebase becomes huge and difficult to understand. People think that managing microservices will be much easier. That’s true when developers focus on individual microservices. But understanding of distribute system could be much harder and it is often ignored when making decision to split.
- Microservices can scale independently, consuming less resources. Indeed, microservices can be scaled independently. But it requires additional infrastructure: message brokers, load balancers and service discovery . It make sense to calculate total costs in advance.
- Microservices can be released independently, decreasing time to market. For minor changes it is usually true. Bigger updates require API changes and affect multiple services. Maintaining compatibility is required now: microservices are deployed independently. Work of multiple teams have to be coordinated. (Automated) system integration testing is also required now.
- Microservice envy: Everyone is seems to be doing microservices nowadays.
Apart from mentioned above, some effects that may happen are:
Local calls are replaced with remote calls
- Remote calls are way more expensive than local ones. Performance usually degrades.
- Incorrect identifying of components (and bounded contexts) will cause too many internal calls. In this case some internal calls will become remote calls causing extra latency.
- Identifying system subdomains and defining concise interfaces between this subsystems is The Challenge. This process should start in monolithic system so it should be refactored first into multiple logically separated modules working together as single system.
Further splitting, if necessary, would be much easier. See Domain Driven Design
Security: Leaking of sensitive data
Migrating to microservices may improve or decrease overall security of the system.
Shrinking boundaries of where sensitive data is stored and processed can significantly relax security restrictions for not-affected components thus simplifying development and security audit (see PCI de-scoping)
Incorrectly defined system domains may cause transferring of sensitive data from one microservice to another causing in turn leaking this data to messaging systems and logs. In-transfer data encryption becomes a requirement, causing requirement to do proper secret management.
Call tracing becomes harder
- In unhappy scenario troubleshooting may become very hard or even impossible.
- Requests and responses now require correlation IDs (
X-Request-IDHTTP headers, including correlation ID in message envelope/payload)
- Logging should also include correlation IDs
- Distributed log management and tracing system is now required. Some tools that could help are Zipkin, AWS X-Ray, Spring Cloud Sleuth, ELK Stack.
API Contracts is now mandatory
- Independent teams should rely on well defined API contracts.
- API consumers have their own release cycle so API changes should be backward compatible. Sometimes, multiple different API versions must be supported. Try to avoid supporting more than 2 versions (current and previous).
- API consumers may be forced to update their integration due to API changes.
This list is not comprehensive. It just heights some problems and challenges of the distributed architecture.