I’ve been reading a lot about microservices lately, starting with the excellent Building Microservices book by Sam Newman, and then devouring various blog articles on the topic – including this article by Martin Fowler and James Lewis which provides a nice introduction if you’re new to the topic. Here’s my take on why this style of architecture is worth paying attention to.
In the early days of agile…
While reading about microservices I was reminded of the way I felt back around the the year 2000. At that time, agile software development concepts were just starting to have a bigger impact on the software development community – at least in my neck of the woods. These concepts were still not main stream by any means, but a lot more people were starting to talk about them and the more adventurous among us were trying out Scrum or Extreme Programming.
I recall thinking how the concepts behind agile just made sense. Here was a highly disciplined yet lightweight way to build great software quickly, and to adapt to changing requirements along the way. There was no doubt in my mind that software development was destined to become more agile over time, and the years since have proven that prediction correct. While not every company is a great model of the agile manifesto in action, even the most conservative software organizations can’t help but take notice of this trend.
Agile architecture and design?
In those early days, a lot of people were uncomfortable with agile concepts. People couldn’t imagine running a software project without a gantt chart, or without spending months on requirements and design before starting to code something significant. Many people still feel this way.
Agile supporter though I was, one part I had trouble with was the idea of “no big design up front” – and I wasn’t alone.
If you want to build a doghouse, you can just get some wood together and get a rough shape. However if you want to build a skyscraper, you can’t work that way – it’ll just collapse before you even get half way up. — Martin Fowler
Leaving detailed requirements to the last possible moment didn’t bother me, and I was happy to throw gantt charts out the window, but how could you create anything other than a big ball of mud if you didn’t stop to think about the major components of your software and how they would fit together?
I can’t tell you how strongly I believe in Big Design Up Front, which the proponents of Extreme Programming consider anathema. I have consistently saved time and made better products by using BDUF and I’m proud to use it, no matter what the XP fanatics claim. They’re just wrong on this point and I can’t be any clearer than that. — Joel Spolsky
While I agreed that going into a lot of detail on architecture and design was certain to be a waste of time, I couldn’t see how people could develop quality software without some sort of architectural framework being described and agreed upon up front. I told myself that “no big design up front” didn’t mean no design up front, the same way that “travel light” didn’t mean “don’t write any documentation” and moved on. I would do just enough architecture and design to feel comfortable before getting down to the business of coding. Anything less would be irresponsible.
Over the years though, just a little bit of discomfort remained. I kept seeing people I respected in the agile community talking about deferring architecture and design decisions to the last responsible moment, but I couldn’t imagine a world where the last responsible moment would be anything other than the right near the start of the project – at least in cases where multiple agile teams were collaborating to build a large product together. Which takes us back to microservices…
Agile architecture and design!
Everything I’ve read about microservices leads me to one conclusion: this is a model that supports a much more agile and evolutionary way to architect and design software systems. Microservices make it safer to defer what would normally be architectural decisions without worrying that you’re headed for a massive rewrite in the future.
By developing system capabilities as independently deployable services, you have a lot more freedom to evolve your system as things change over time. Each microservice is free to use its own programming language and its own persistence mechanisms. Faults that might take down an entire monolithic application can be more easily handled so that only a small area of the application is impacted. “Walk before your run” deployment options are more easily supported, with new versions of microservices deployed alongside older versions to gain confidence or to explore alternatives. If a problem is found, you only need to roll back a small portion of the system, not the system as a whole.
In other words, developers have the freedom to experiment, explore, evolve the software, and to do what they think is right.
Everything old is new again?
In many respects, microservices and the concepts behind them are nothing new. Wasn’t object-oriented design supposed to provide the same kind of advantages? Loose coupling, cohesion, adaptors, single responsibility principle, clear interfaces, automated tests, message queues and events; none of these are new concepts. Domain-driven-design (DDD) has been around for many years with Eric Evans’ book on the subject published in 2003. So why all the noise now about microservices?
It’s all a matter of degrees
What’s different, I think, is that microservices take these concepts to the next level. Microservices make it easier to get loose coupling and cohesion right so you can refactor not just your code – but your system – with relative ease. They make it easier to do the right thing at the system level, and harder to do the wrong thing.
Microservices especially excel in enabling multiple teams to write, maintain, and evolve different parts of the system without as much impact on other teams. They provide for a natural mapping between multi-team organizational structures and your software structure. They support and encourage the model of cross-functional agile teams working to provide vertical slices of business value.
To those who point out that almost all of these benefits can be realized in a well-designed and well-developed monolithic architecture – you’re of course right. You can design your monolithic system as a set of components that achieve many of the same benefits. If you like, you can even go so far as to run each component in its own thread or set of threads, and use message queues and callbacks for communication between components. I worked on a system that was architected like this back in the 1990’s and it worked quite well.
A component-based architecture offers a middle ground that may be attractive and appropriate for many. It lets you avoid some of the downsides of microservices – but you’ll also lose at least some of the benefits like the ability for teams to easily choose the most appropriate language for the job, the ability to independently deploy only the parts of the system that have changed, or to easily scale parts of your system without the need to change any code at all. When it comes to microservices, the whole is greater than the sum of the parts.
Not a panacea
All this said, of course microservices are not panacea. Having microservices in your tool belt doesn’t mean you should automatically use them everywhere. As Sam Newman points out in his book, distributed systems are hard, and starting out with a monolithic application when the system is small and when you don’t yet have a clear idea of where to draw the boundaries between microservices probably makes sense.
Microservices also require a significant investment in DevOps automation before you can even get started. While they simplify things in some very important areas they also increase complexity in others. For an excellent summary of some of the downsides of microservices, I recommend Benjamin Wootton’s post on the subject.
An idea whose time has come
I believe that the advantages of a microservices-style of architecture are strong enough that more and more product development teams will adopt this style of architecture over time. We’ve already seen many respected organizations adopt this style with real success, including big names like Netflix and Spotify.
As more products are developed using this style, teams will increasingly benefit from the knowledge gained and tools developed by others to address the complexities of this approach. Tools and frameworks that make it easier to deploy, orchestrate, and monitor systems of microservices are already becoming more common, and will decrease the automation and operational burden on teams.
I believe that microservices-based architectures are a trend with staying power – and not a here-today, gone-tomorrow fad. Yes, there is a lot of hype around microservices these days, but that hype is founded on strong principles and real successes.