Showing posts with label architecture. Show all posts
Showing posts with label architecture. Show all posts

Sunday, 16 March 2014

The microservice declaration of independence

Recently, an article on microservice architectures by my colleagues Martin Fowler and James Lewis has caused some mild controversy in the Twittersphere. For example, Kelly Sommers said:
I’m still trying to figure out what is distinct period. Maybe I’ll accept the name once I see a diff
I have yet to find someone who believes it a bad idea to build systems from small, loosely-coupled services that can be independently changed and deployed. The hesitance that some have shown for the term "microservice architecture" derives from their doubt that the term adds anything above and beyond the well-worn term service-oriented architecture (here described by Stefan Tilkov).

This is a serious charge. The value that concepts like "microservice" have is in their use for communication and education. If all a term does is to add to the menagerie of poorly-defined architectural buzzwords, then we might be better off sticking with the poorly-defined buzzwords we're already familiar with.

On the other hand, that ideas of such uncontroversial value are still worthy of discussion is some indication that there is room for improvement in the current conceptual landscape.

In order for "microservice architecture" to be a useful way of characterising systems, it needs an accepted and well-understood definition. Mark Baker laments the lack of a precise description, because he feels its absence compromises the value of the term:
Really unfortunate that the Microservices style isn't defined in terms of architectural constraints #ambiguity #herewegoagain
In their article, Martin and James have this to say about the style's definition:
We cannot say there is a formal definition of the microservices architectural style, but we can attempt to describe what we see as common characteristics for architectures that fit the label.
I'm still optimistic that a clearer picture is yet to emerge, though it might not be as unambiguous as the REST architectural style, which is defined in terms of six constraints.

My own opinion is that microservice architectures can be understood through a single abstract architectural constraint which can be interpreted along many different degrees of freedom.
X can be varied independently of the rest of the system.
What might X be? There are many qualities that might be locally varied in an architecture to beneficial effect. Here are some ways we could introduce novelty into a service without wishing to disturb the greater system:
  • Select implementation and storage technology
  • Test
  • Deploy to production
  • Recover from failure
  • Monitor
  • Horizontally scale
  • Replace
There are other aspects of systems that are harder to formalise, but which the human beings that work on our software systems might wish to do with without being troubled by the fearsome complexity of the whole architecture:
I don't wish to imply that this is an exhaustive list. To me, the commonality lies in the concept of independent variation, not the kinds of variation themselves.

Monolithic architectures are monolithic in the sense that they have few or no degrees of freedom. This may be a perfectly valid choice. The more degrees of freedom available in a system, the more coordination is required to keep the disparate parts of the system working together.

For example, a human shoulder is well articulated. This makes it an amazingly flexible subsystem. I can touch my toes, reach above my head and even scratch my own back. On the other hand, the infrastructure required to support such free movement is quite complex and therefore fragile. My right shoulder is currently broken. However, if it were simpler and flexed only in one direction there is a good chance that it would have been able to withstand the impact undamaged.

(Luckily, my shoulders are able to fail independently and therefore my left is still in good working order!)

Systems suffer when architectures are not articulated in the directions they need to be. We may wish to horizontally scale, but are unable to isolate two parts of the system which exhibit very different behaviour under load. We might wish to enable two teams of people in different countries to work on different features, but find that they step on each others' toes because they are hacking on the same deployable artifact.

I value the concept of independence because it gives me a way of evaluating architectural choices beyond "microservices are good" and "microservices are bad". Degrees of architectural freedom are valuable, but they may or may not be worth the effort required to sustain them.

For example, independent deployment is useful because you don't have to stop the whole world to introduce a change in a small part of the system. To steal an example from conversation with James, a bank would not want to stop processing credit card transactions in order to release a new feature on its mobile app.

However, once you move away from monolithic deployments, API versioning and backwards compatibility are required to coordinate releases. That can be hard work, and if you never need to exercise your ability to upgrade a part of the system in isolation, then that work might be wasted.

I've worked on a system which had two services that talked to each other through a poorly designed API. Every time one service changed, the other had to as well. Backwards compatibility was almost impossible to maintain due to some very bad design choices we made early on. Consequently, we almost always had to do double deployments.

In the end we merged the two repositories holding the two services and started deploying them simultaneously. We lost the ability to take one to production without the other, but in our situation that was more a trap than a valuable feature. The two services continued to be distinct as runtime entities, but they now evolved along a single timeline.

This brings me to how I think service-oriented architecture might relate to microservice architecture. Stefan's fourth principle of service-oriented architectures is that services be autonomous:
Services can be changed and deployed, versioned and managed independently of each other.
Personally, I see that as the principle attribute from which all others derive. However, under that definition the two services that my team merged no longer qualify as such, at least not in terms of traditional service-oriented architecture. We consciously gave up the ability to change, deploy and version them independently.

However, I would argue they still qualify as micro-services. We could understand and discuss them separately. They had distinct responsibilities. We could monitor, diagnose and restart them separately in production. If we'd wanted to horizontally scale one without the other we could have. It just happened that on the evolution axis we did not require independence.

According to the terms of the suggested constraint family that "X can be varied independently of the rest of the system", traditional service-oriented architecture could be seen as a specific set of values for X. Some of the degrees of freedom that were important 10 years ago are less important now. Most are still relevant. New kinds of variation that have risen to prominence.

I don't think that microservice architectures are a break from the past. I would probably characterise the movement as a kind of neo-SOA that is trying to get back to the roots of the original movement. But I do think that microservice architectural analysis has a different and more general preoccupation than service-oriented architectural analysis because it revolves around the notion of independent variation itself, rather than prescribing certain kinds of independence.

Saturday, 25 May 2013

Goldilocks services

Github is a document store. Each repository is a document. Transactions are easy to execute within a
document and only eventually consistent across documents.

If your documents are too large, the scope of your transactions will be excessive, and you will get contention. If your documents are too small, the scope of your transactions will be insufficient, and you will be forced to manage changes across multiple transactions.

Each service is an aggregate root, so design them so that they can be evolved independently. 

Wednesday, 18 May 2011

Domain-driven teams

I just watched Phil present on why enterprise architecture usually sucks, and it struck me that his talk resembled a formal argument:
  1. Design always reflects team structure (Conway's law)
  2. Design should reflect the business domain (Domain-driven design)
It seems to me that the following conclusion is inevitable:
  1. Therefore, team structure should reflect the business domain
Logically, Phil's maxim that "what’s easy to change in the business model should be easy to change in your architecture" can only be achieved by structuring teams around domain concepts and avoiding cross-cutting concerns.

Sunday, 28 November 2010

Architecture is the opposite of surprise

Architects often disagree on technical matters. But there's also a surprising amount of disagreement on what software architecture actually is. Here are a few definitions that I've come across:
  • an abstract description of the system
  • work done by developers with the title "architect"
  • that diagram with clouds and arrows that somebody put on the network drive at the start of the project before we really knew what we were building
  • that document signed by the client at the start of the project before we really knew what we were building
The problem with all these definitions is that they imply that systems that don't have architects don't have architectures. Any definition that can't cope with the majority of applications that have emerged without considered architectural analysis isn't very useful.

Martin Fowler's definition is more useful and widely applicable. He suggests that software architecture is the set of “things that people perceive as hard to change.” [PDF] This characterisation is successful because it shifts the focus from the production to the consumption of architecture.

Fowler's definition challenges the intentional fallacy as it applies to software architecture, which is the idea that the meaning of a text belongs to its author. Fowler's architecture can therefore include elements that were never deliberately envisaged by an architect, which in turn lets us consider systems that never had an architect.

A similar idea was advanced in the essay The Death of the Author by the literary critic Roland Barthes:
As soon as a fact is narrated no longer with a view to acting directly on reality but intransitively, that is to say, finally outside of any function other than that of the very practice of the symbol itself, this disconnection occurs, the voice loses its origin, the author enters into his own death, writing begins.
Substitute "architect" for "author" and "development begins" for "writing begins" and Barthes could be talking about what happens when a carefully prepared architecture document is handed over for implementation.

Claude E. Shannon's information theory formally analyses the consumption of texts. He measured the information content of written English by showing test subjects a truncated piece of English text and asking them to guess what letter would come next. They guessed correctly about half the time (which means that English contains roughly 1 bit of information per letter).

The beauty of this experiment is that Shannon didn't need a model of his subjects' knowledge of English. All he had to do was observe was what happened when they applied that knowledge.

Implicit in Shannon's experiment is the idea that English is the sum of all cues that inform speakers as to what could come next. Following his approach, I would define architecture as the sum of all cues that suggest to a developer how a feature should be implemented in a particular system.

These cues can take many forms. Perhaps the arrows and clouds diagram tells a developer in which tier of the system to put a particular piece of logic. But developers are also guided by the language used by stakeholders, organisational structure and the culture of the technology stack.

Under this definition, the more prescriptive a system's architecture, the less information developers need to absorb in order to understand a given feature. In other words, architecture is the opposite of surprise.