Quite a few of our clients are looking at microservices, and a popular question we often get asked is "what's the biggest mistake you see with microservices?". We've seen plenty of good things with this architectural pattern, but we have also seen a few recurring issues and anti-patterns. Last year Tareq Abedrabbo, CTO of our sister company OpenCredo, created a great talk (and blog post) entitled "The Seven Deadly Sins of Microservices". Tareq and I had some fascinating discussion around the anti-patterns he identified, and this prompted me to create a spin-off that combines both ideas from Tareq's and my experiences of helping our clients to implement microservice-based architectures.
I've been fortunate to present this new talk at both QCon New York and Devoxx UK, and I'm keen to share the overview slide of the presentation to get the discussion started. Here are my 'seven deadly sins of microservices':
Let's dive into these seven anti-patterns and provide a bit more explanation:
Here at Container Solutions, we certainly aren't shy about using the latest and greatest technology - in fact, this is pretty much core to our philosophy. However, we always talk with our clients about using the most appropriate technology for their goals, problem or use case. We are strong supporters of technologies such as Docker, Mesos and Terraform, and we know the value they can bring to an IT team, but we strive to work with an organisation to help them create their strategy and drive the change needed to support the application of this innovative technology.
Where ever there is choice in technology, we often get to see lots of variation within a large organisation, and with microservices this variation can often be found within the communication protocol. The resolution to this anti-pattern is to know your options - HTTP, ProtoBuffs, Thrift, AMQP, MQTT etc - but attempt to standardise on the use of one synchronous and one asynchronous protocol - "Don't gold plate, but know your options"
The 'greed' anti-pattern revolves around discussion of the organisational, people and cultural impact that introducing microservices has (hint - this is bigger than most people appreciate!). I've written more about this in an OpenCredo blog post "The business behind microservices: Exploring the organisational, architectural and operational challenges"
It is all to easy to become lazy when implementing microservices, and as soon as you can't deploy services independently, what you have is a distributed monolith. The slide deck below contains several references and links to explore in order to avoid this, but the core principle is to be mindful of your service boundaries and APIs. And when I say 'mindful' I'm really alluding to the fact that your designs and contracts must be verifiable and enforceable automatically!
The vast majority of microservice systems are going to be running as distributed systems, and therefore we must respect this (both as developers and operators). As developers we need to code defensively, and utilise fault tolerant patterns, such as time-outs, retries, circuit-breakers and bulkheads. Michael Nygard's excellent 'Release It!' book should be mandatory reading, as should a visit to the Netflix OSS tooling Github repository! As operators, we need to embrace the 'DevOps' mentality of shared understanding and responsibility, and also spend an appropriate amount of time developing and working with tooling to support our role. Adrian Cockcroft has recently presented a talk with some excellent pointers as to the challenges with monitoring microservices and containers.
With a monolith the notion of developing a single shared domain model was often a key pattern, as this would be used throughout the code base. However, with microservices the Domain-Driven Design (DDD) principles of 'bounded contexts' have become popular, and support us in properly encapsulating our domain models
Testing with microservices is hard - this is simply a fact. However, hard does not mean impossible, and accordingly we need to create new tooling and processes to support testing in a fast-moving, volatile and transient world. In my talk I referenced the good work by Toby Clemson in sharing his 'Testing Strategies in a Microservice' architecture', but much work still needs to be done. Many organisations that have been creating microservices for some time are arguing that the only effective way to test microservices is in production, because the emergent behaviour of the system is impossible to predict in a synthetic staging environment.
The full slide deck for the talk can be found on my slideshare account, and I'll post a new article as soon as the video recording becomes available:
As usual, if you have any questions then please do leave a comment below or get in touch with us!