Monday, 18 August 2014

What Are Combo-Style Microservices?

Jazz is not a background music. You must concentrate upon it to get the most out of it. - Horace Silver, The Art of Small Combo Jazz
In this first real post, I'd like to introduce the particular style of microservices I want to write about here, for which I'm trying out the name "combo-style microservices". I reserve the right to think of a better name in the future!

To understand this style, it's helpful first to look at the emerging standard definition of microservices as defined in Fowler and Lewis's seminal post. They describe building an application out of many small components, each independently developed and deployed, making service requests from each other over a simple routing system (HTTP or lightweight messaging). Components are naturally called "services" since each provides a menu of services to other components, available over API calls; by one means or another, e.g. through service contracts, these API calls are published and maintained so they can be used reliably. Each service provides a full business capability including a user interface and data storage, if those are needed.

I liken this standard definition to a large orchestra all playing a symphony together - it requires a high degree of co-operation, communication, and orchestration. The co-ordination may be centralised in the person of a conductor or distributed as in a self-conducted orchestra, but in any case, the musicians must come to clear agreements about many things: who is in which section, how fast to play, whether to include all the repeats, and much more. And while performers can make their own decisions about matters that affect just them - say, when to turn the page in the score - no member can make even the slightest externally audible change unilaterally. If the oboist decides to play fortissimo instead of piano in bar 12 without telling the other players, the whole performance is likely to be ruined as notes are drowned out and players miss their cues. Similarly, while a Fowler/Lewis microservices system can allow its services to make whatever internal choices they like (programming language, libraries, data storage), it has to enforce strict control and testing on externally visible changes, such as changing the return type of a service call or removing it altogether.

Consider instead a jazz combo, a group of musicians who form a much looser combination with minimal co-ordination. They agree on a few basics - the key and the chord progression, for example - and then improvise rhythm and melody separately based on these. Minor audible changes, such as an embellishment of a theme or a new countermelody, are expected and welcomed by other players, who ignore them or respond to them based on their own view of the evolving music. Even significant modifications like bringing in an additional musician to "sit in" are acceptable and add to the overall musical experience. Because its members have so much freedom to improvise, no two performances by such a combo are the same.

In a combo-style microservices architecture, we strive to replicate the jazz combo's flexibility and independence. We retain the notion of building our application from many small components, each developed and deployed independently and providing a business capability - but the components no longer make API calls to each other. Instead, each component publishes one or more business-meaningful facts (such as "Billy has purchased Legos for £20") using a ubiquitous language, and other components subscribe to those results they are interested in. The collection of all results is stored in a fact database that can later be searched ("find all toy purchases in the last five minutes for over £20”). If you like, think of the components as micro-applications, each one performing a useful small task like "compute sales tax" or "authenticate user", and the whole producing the required behaviour for users. The musical combo co-ordinates its work through the basic agreements on key and chords, which change little if at all during a single musical piece, just as our microservices combo co-ordinates through the common and (we hope) relatively stable language of the domain; in both cases, individual participants can vary their behaviour quite substantially without disrupting the activities of others.

There are many obvious objections to the practicality of such a system: it will necessarily have some emergent behaviour, the language or the domain may not be sufficiently stable, the publish/subscribe model may not perform. I shall try to address some of these in future posts (and perhaps will convince myself that the ideas need modification!) but I hope this explanation has helped make clear where I currently stand.

(Thanks to Antony Marcano for inspiring the jazz-and-orchestra comparison.)

Edit: I noticed later that the Fowler/Lewis microservices post has one reference to an earlier Fowler article on Event Collaboration, which describes an event-based design similar to the combo style. (An interesting difference is the lack of a fact database - an exercise for the reader is to determine how the example at the end of the Fowler article is simplified if you introduce one.) This is encouraging - maybe I'm not alone in thinking combo style! - but on reflection I still think it's fair to say that the microservices post largely assumes that components will call each other via APIs, with references to consumer-driven contracts, published interfaces, and coarse-grained API design.

No comments:

Post a Comment