Top 5 pitfalls to look out for when deploying microservices
Every once in a while, specific architectural patterns are claimed to be silver bullets. They become the go-to way of solving any problem, undermining the design.
In the past, there was an era of service-oriented architecture and layered architecture, both incredible patterns but each with its limitations.
In this blog, we'll take a deep dive into the most famous architectural pattern of the current era: microservices.
We will focus on the main challenges when deploying microservices so we become mindful of when and when not to, instead of using them as a hammer for all problems.
Pitfall #1: Access control of data in microservices is complex
When it comes to controlling access to data in monoliths, the problem is simple: You can have role-based access defined at one of your layers and delegate the responsibility for enforcing the access control.
When it comes to microservices, the problem compounds – either there is a shared library that maintains the access control and has a standard service to which each service talks, or in the worst case, each service goes and implements its authorization layer.
So the complexity of building an authorization layer is much greater than a monolithic system, and depending on the implementation, it can significantly slow down the rollouts of new roles or access control policies.
Pitfall #2: Distributed transactions in microservices are complicated
Imagine booking a holiday package, which gives a discounted price for hotels and flights; let’s say your hotel booking goes through but not your flight booking.
What would you do? Transactions guarantee either both bookings succeed or neither of them. They guarantee consistent behavior across multiple writes.
Such guarantees across different services are complex; you can use two-phase commits or saga patterns to ensure consistency. However, these distributed patterns are complex, challenging to reason, and can come with performance penalties.
Pitfall #3: Aggregating data in microservices is challenging to optimize
When fetching data from multi-services, applications need to take care of complex aggregations, and they could lead to massive fan outs due to N+1 queries and similar problems.
It’s challenging to do optimizations like predicate push-downs for microservices; most naive implementations will call the microservice multiple times or fetch more data than required.
Looking at this example, to show a holiday package, we need to call different services multiple times to offer other options for hotels/flights and rentals.
Pitfall #4: Observability in microservices is often elusive
Monitoring or triaging an issue across multiple services can be tricky without the right system; your workflow could fall apart due to a downstream system you are unaware of.
It can be complicated to pinpoint an issue in production or debug which system is causing the outage. To tackle these problems, we can set up distributed tracing and monitoring, but that adds to infrastructure complexity and cost.
Pitfall #5: Infrastructure complexity in microservices is costly
To make microservice work, you must invest in various infrastructure pieces to make services easily deployable, scalable, and traceable. You also need the correct monitoring and alert setup, which adds to the terms of cost and management.
To be productive with microservices while ensuring minimal outages and downtime is challenging. Ultimately, the cost of maintenance overshadows the cost of implementation, and it’s true for microservices.
Conclusion
Microservice is an excellent architecture pattern for the correct set of problems, but it shouldn’t be the go-to pattern for all issues. This post shows that many challenges come in a microservices architecture, some non-trivial.
In our next post, we will discuss monolithic architecture and how to work with its challenges.