Sunday, February 7, 2016

The architectural idea of microservices was inspired - in part - by Unix's philosophy of code being short, simple, clear, modular, extendable and
that it could be repurposed by developers. The term is currently up there with Internet of Things, Big Data and the Cloud,
in contemporary technical lexicon.

scaling - because services are independent they can be independently scaled

deployment - deployment should be easy. A change to a service means that's all that's deployed.

It is worth pointing out it isn't just a book about microservices. Many of the ideas and best practises detailed (for example HATOES in your ReST approach and to check OWASP for security references) are equally applicable to non - microservices architectures. But, that said, what I really like about this book is anytime a general architectural or software engineer concept (and there are a lot) is explained it is explained very well. Some examples:

Reactive extensions (running operations as a result of multiple calls not caring if they were blocking / non blocking. For ref: see here and here).

There are - of course - many tips regarding how you approach microservices. For example:

Don't get too hung up on DRY. It may make it harder to keep your services independent.

Consider using CDC's for your testing approach

Canary releasing / Blue, Green testing for releasing.

Using bulkhead and circuit breaker patterns to make services ore resilient.

As an overview to microservices, it's a great book. However, the reader must bear in mind there is no one size fits all approach to microservices.
The finer details will depend on your project, your team and even a bit of trial and error. It's difficult to critique this book. So instead,
I'll just flag some concerns not about the actual book but about microservices in general and how the industry and developers are reacting to them.

My first concern with microservices is more a practical than a technical one. Doing modular design for everything from your
schema, service layer, end points, configuration isn't as easy as some people might think. Especially in teams of varied skill level,
varied backgrounds and inevitable commercial pressure that happens in every project. It requires a lot of technical aptitude, leadership and discipline.
If a project is not good at achieving modular design in a monolith - for whatever reason - I think it will really struggle at modular design in microservices when the complexity of the network has to be also considered.

The second concern I'd have is that when explaining the principle ideas of microservices, it is often compared with a monolith to the point the word monolith is a pejorative term. The two approaches: monolith and microservices are presented as if it's either one or the other. I think this a false dichotomy fallacy. There are other approaches available.

Thirdly, microservices are no doubt, a clever idea. But that doesn't mean there are a panacea. In some projects they will be a good fit, in others they will not be worth it. One obvious factor to bear in mind is your non-functional requirements. One useful point of reference, that is worth considering is the project James Lewis (another Thoughtworks guru) described in his talk about microservices in 2012. In this presentation, three non-functional requirements for the project caught my attention:

One component had to handle 1,000 TPS

Another had to support a user base of 100 million users

Another had to support batch loads of 30 - 90 million records

While I am not saying you should be in this ballpark before considering microservices, I am just trying to suggest that most projects don't have these sort of demands and there's a lot of merit of considering something like a very well structured modular monolith first using DDD principles and then to migrate towards microservices should the benefits justify it. This strategy is well explained by Martin Fowler in his Monolith first article.

When developing a rapid prototype it can make sense to put the emphasis on the 'happy path' and not consider things like exception handling, edge cases and failure. Perhaps, once the prototype phase of the project is over the code will be thrown out or it will be refactored to deal with the real world.

In a production system we simply don't have luxury to only consider the happy path. The more production system I have worked on the more types of failure I have being exposed to - some of it very painful. As my hair went greyer from these experiences, I couldn't help thinking more and more about how to make failure less painful. Who wants their pager going off for some silly reason? Nobody. If dealing with production code, we simply must think about how best to deal with various forms of failure.

In this presentation I consider two engineering techniques that I think should always be on the architectural radar:
* Fail fast
* Fail safe

About Me

Alex Staveley is a software professional passionate about software
engineering and technical architecture. He blogs about architectural
approaches, Java topics, web solutions and various technical bits and
pieces.