At the end of 2014, Tareq Abedrabbo, CTO of OpenCredo, published a post titled “The Seven Deadly Sins of Microservices“ in which he identified seven common anti-patterns of developing in a microservices architecture. In January 2016, Danial Bryant from Voxxed published a Redux version of the post, updated to combine his experiences with the original post.
The first issue that both discussed is building the wrong thing. This may be caused by a lack of clarity when defining the project’s scope and objective, as mentioned in Abedrabbo’s article, or by attempting to use the latest and greatest tech, rather than the most appropriate for the specific goals, as per Bryant’s. Both scenarios can lead to additional, unnecessary complexity through a lack of focus on the project’s ultimate objective.
Failing to adopt a contract-first design approach is another way a project can be lead astray, according to Abedrabbo. A good service contract allows developers to focus on what the microservice does, rather than how it is implemented, making sure the overall objective is the main focus.
The technical implementation details still need to be addressed, and both Abedrabbo’s and Bryant’s articles raise the issue of creating a distributed monolith by applying monolithic concepts to a microservices architecture. This crossover between monolithic and microservices architectures also exposes the issue of a shared domain model. Since applications are now commonly made up of multiple microservices, an application is no longer a single entity with rigid boundaries, as was the case with traditional monolithic architectures. Developers can overcome this issue by adopting a Domain-Driven Design (DDD) approach offering an evolving model of core business concepts is more appropriate.
Both articles also express concern over selecting the wrong, or too many, communication protocols for exchanging messages. The capabilities of the service should influence the protocols, and a good approach is to take a standardised stance and use one synchronous protocol for external services, and one asynchronous protocol for internal services.
Abedrabbo highlights the importance of introducing proven DevOps practices right from the start to take advantage of a continuous delivery pipeline, as microservices allow. It follows up by encouraging the automation of acceptance, regression and performance testing from early on too, with Bryant extending this theme to ensure the system supports this testing in the fast-moving, and often volatile, world of microservices.
This notion of DevOps is carried through in Bryant’s article to encourage the mentality of shared understanding and responsibility between operators or sysadmins. He suggests that staff must be trained to deal with real-life disaster recovery so that problems and successes can be shared throughout the team
This human factor brings us to the final point from the original article. Microservices can simplify development and promote a collaborative ethos, but developers accustomed to traditional, large-scale organisations full of silos and politics may not have the bigger picture understanding of how the broader system works and how the services behave at runtime. Organisations can overcome this issue by investing in developers and encouraging organisation-wide collaboration to allow the building of better, more sustainable systems that can take advantage of microservices’ capabilities.