While microservices have been around for a while, they have recently gained significant traction as the basis for a software architecture in organizations looking to modernize their enterprise IT systems. Microservices are essentially an architectural style, where an application is structured as a collection of small, self-sufficient, domain-specific services that can be deployed and tested in isolation. And their core value proposition centers around their ability to get software to market faster, by having teams work on these independent application components, speeding up both bug fixes and the addition of new features. While the benefits of microservices are clear, relatively less has been written about the challenges associated with their implementation. In this post, we will look at some of the tricky issues that microservices can introduce.
#1: Distributed transactions increase complexity
Transaction management is simpler in monolithic applications because they consist of a single, common database server. Transactions can be initiated at the database level and committed or rolled back depending on the final outcome of the transaction. But, with microservices, each service is a system apart with its own database. This presents a whole host of complexities when it comes to the process of committing a transaction.
Think of an e-commerce application that takes orders from customers, verifies inventory and available credit, and ships them. In a distributed scenario, the architecture would be split into a dozen smaller services like user handling service, payment gateway service etc., each with their respective database. The application cannot simply use a local ACID transaction, because there is no direct and simple way of maintaining ACID principles across multiple databases. This is where the key challenge lies when it comes to transaction management in microservices.
#2: Testing microservices can be cumbersome
Testing microservices-based applications is not easy. In addition to testing each microservice individually, the APIs must also be tested to make sure they are all seamlessly communicating with each other. The sheer number of services that make up an application, alongside the dependencies between these services can create complexities in the testing process. For instance, a tester would have to carefully analyze multiple logs across each of the various services in order to write effective integration tests. With several independent teams working simultaneously on distinctive functionalities, it can become quite challenging to pick an ideal time window for extensive testing of the entire software and coordinate overall quality assurance.
#3: Operational challenges can increase
Because your operations teams need to manage an entire ecosystem of services rather than just one application, the ability to instantly provision servers becomes an important prerequisite. If it takes days or months to provision resources, you cannot keep up with the pace needed to make the most of microservices. You need to provision and bring down infrastructure automatically, as these services are scaled up and down. Plus, the capability to provision must be distributed across a larger team, instead of just one senior Dev or DevOps person.
You should also be prepared to address multiple failure issues, such as system downtime, slow service and unexpected responses. Here, you will likely need a load balancing strategy that is much more complicated than for monolithic applications.
Furthermore, with so many services to manage, each with its own language, platform and APIs, you are likely to encounter many issues that were left undetected in your testing environment. Therefore, it becomes important to ensure robust monitoring to manage the entire infrastructure and detect serious problems quickly.
#4: Lack of cultural readiness
The microservices approach requires teams to be reorganized into self-contained, autonomous teams, to ensure that every service is developed, tested, deployed and maintained individually. One tenet of this approach is that organized teams need to follow what Amazon calls the “two-pizza box mentality” – as in, create smaller, cross-functional teams that can be fed with two pizzas for dinner (less than ten people). Each team should be balanced with expertise across Dev, Test, Ops, DB administration, UX, and even product management in some cases.
While this may augur well for teams’ individual efficiencies, it may lead to certain challenges for the organization at large. Teams may end up losing visibility into what other teams are working on, with each service becoming a black box of unknown functionality and purpose. This can hinder understanding of the overall system, resulting in duplication of work and added complexities. If responsibilities are not clearly defined, it can also lead to a lot of finger pointing and blame game.
As application development trends keep evolving, the debate between leveraging microservices or using traditional monolithic architectures will only become more pronounced. If you are looking at microservices, it’s worth taking a step back and considering all of these complexities as you build your strategy. A good way to begin understanding the challenges is to start with small services that are easy to extract, so you can achieve faster results and gain early experiences. This will help you track and gauge the trade-offs related to that particular application and environment. And as you gain these early experiences, it will become much more reasonable to further invest in microservices.
If you want to find out more about how you can leverage microservices for your business, you can contact us.