Be Software Architecture Wise
Be Wise Apps

Leer en español · Lire en français · Auf Deutsch lesen

Chapter 6 of 12 · Intermediate to advanced

Architectural Styles II: Distributed Systems

This chapter takes architecture across the network. It explains when distributing a system is worth its cost, the fallacies that make it harder than it looks, and the main distributed styles: service-based architecture, service-oriented architecture, microservices, event-driven, serverless and space-based architecture. It then covers the mechanisms they all depend on: synchronous and asynchronous communication and API design, consistency models and the CAP theorem, and distributed transactions with sagas and the outbox pattern. It is written for developers and architects who are designing or reviewing systems made of many services, and it is precise about failure, delivery guarantees and consistency.

Video introduction to Chapter 6

7 min · narrated, with captions
Listen only (audio)
Read the transcript

Welcome to Chapter 6: Architectural Styles, part two, Distributed Systems. Chapter 5 described styles in which the whole system is deployed as one unit. This chapter takes the same questions across a network. It explains when distributing a system is worth its cost, the main distributed styles, and the mechanisms they all depend on. And it is precise about failure, delivery guarantees and consistency.

Almost every system of any size is now distributed in some way. A mobile app talks to back-end services, which call payment providers, mapping services and message brokers, and the services themselves run on many machines. Splitting a system can bring independent scaling, fault isolation, independent releases and autonomous teams. It also brings problems that cannot occur inside one process: messages lost or duplicated, services that are slow rather than dead, data that disagrees between copies, and failures in machines you did not know you depended on.

The chapter is rated intermediate to advanced. It is written for developers and architects who are designing or reviewing systems made of many services. It builds on Chapter 5's styles and Chapter 2's qualities, now under network conditions. In particular, it uses availability in series and parallel, coupling and Conway's law, and the architecture quantum, the modular monolith and bounded contexts. And it leads into Chapter 7, which deals with the hardest part of distribution: the data.

The single most important idea in the chapter is that distribution is a trade, not an upgrade. Each benefit is bought with latency, consistency, observability and operational effort. A good architect can say which benefit is being bought, at what price, and why a cheaper option inside a monolith will not do.

The chapter moves from why to how. Section six point one sets out the reasons to distribute, the eight fallacies of distributed computing, and partial failure, and gives you the arithmetic to price the trade before you commit to it. Section six point two covers service-based architecture, a pragmatic middle ground of a few coarse domain services, and the classic service-oriented architecture, including why it fell out of favour. Section six point three covers microservices: services aligned to bounded contexts, independent deployment, a database per service, how to decide how big a service should be, and the distributed monolith. Section six point four covers event-driven architecture: events and commands, brokers and mediators, delivery guarantees, and consumers that can safely receive the same message twice.

Here is the arithmetic from Section six point one. Placing an order passes through five services: the API gateway, then order, menu, pricing and payment. Each waits for the next to answer, and each on its own is available ninety-nine point nine per cent of the time. But availabilities multiply. Together they give a request path of only about ninety-nine and a half per cent: about three point six hours of downtime a month. And latencies add. With twenty milliseconds of work in each service, plus a little for each network hop, the median is about a hundred and ten milliseconds. Five individually respectable services have produced a much weaker request path. That is the price of distribution, worked out on paper before you build anything.

This diagram shows partial failure, the defining problem. An order service asks a payment service to authorise twenty four pounds fifty, and waits for the reply. Three different things can go wrong. The request is lost, and no charge was made. The payment service crashes or stalls, and nobody knows. Or the reply is lost, and the card was charged. To the caller, all three look identical: no reply before the timeout. So any operation that may be retried must be idempotent, which means that doing it twice has the same effect as doing it once.

The second half turns to the mechanisms every distributed style depends on. Section six point five compares synchronous and asynchronous communication and the coupling each creates, and covers API design, versioning and contract testing. Section six point six is about what readers of copied data can expect: consistency models, what the CAP theorem really says, and PACELC. Section six point seven explains why two-phase commit is avoided between services, and how sagas, compensating transactions and the outbox pattern keep business processes correct without it. Section six point eight closes with two styles for particular load profiles: serverless functions, which scale to zero, and space-based architecture, which keeps data in memory to survive extreme spikes, such as tickets going on sale.

Three habits run through every section. First, count synchronous dependencies, not services. The number of things that must all be working at the same moment for a request to succeed decides its availability and latency. Second, assume messages are lost, delayed, duplicated and reordered, and design receivers so that a repeated message does no harm. Third, decide who owns each piece of data, because ownership decides where transactions are possible, and where consistency must be managed across services. Chapter 7 develops that habit into a full treatment of data architecture.

If you are new to the topic, read each section's opening summary and the boxes headed If you are new to this first. Experienced engineers will find the precision where it matters. The chapter takes about three and a half hours to read. Two examples recur. The food-delivery platform shows ordinary distributed design. A ticketing system for a stadium tour shows what changes when tens of thousands of people want the same few seats at the same second. Each section ends with a few self-check questions. Answer them in your head before you look. When you are ready, take the optional chapter test: twenty multiple-choice questions and two written answers, in about forty five minutes. The pass mark is eighty per cent.

That is the map of Chapter 6. Start with Section six point one, where we weigh the reasons to distribute against the fallacies that make it harder than it looks. See you there.

Download chapter (PDF)Read in the app

At a glance

You will learn to

  • Explain the legitimate reasons to distribute a system and the costs each reason brings.
  • Describe the eight fallacies of distributed computing and partial failure, and design responses to them.
  • Calculate the availability and latency of a chain of synchronous calls and propose changes that improve them.
  • Compare service-based architecture, classic SOA and microservices, and choose between them for a given organisation.
  • Decide service granularity by weighing disintegrators against integrators, and recognise the distributed monolith.
  • Distinguish events, commands and messages, broker and mediator topologies, and Fowler's four event patterns.
  • Explain delivery guarantees, why exactly-once needs careful definition, and how idempotent consumers work.
  • Choose communication styles, consistency levels and transaction patterns (sagas, outbox) for distributed workflows.

Before you start

Chapters 0 to 5, especially availability in series and parallel (Chapter 2, Section 2.5), coupling and Conway's law (Chapter 3) and the architecture quantum, modular monolith and bounded contexts (Chapter 5).

Time

About 3½ hours to read; 45 minutes for the test.

Key terms

distributed system · partial failure · fallacies of distributed computing · temporal coupling · service-based architecture · enterprise service bus · microservices · independent deployability · database per service · event-driven architecture · at-least-once delivery · idempotent consumer · CAP theorem · saga

Why this chapter matters

Chapter 5 described styles in which the whole system is deployed as one unit. This chapter takes the same questions across a network. Almost every system of any size is now distributed in some way: a mobile app talks to back-end services, which call payment providers, mapping services and message brokers, and the services themselves run on many machines. Splitting a system can bring independent scaling, fault isolation, independent releases and autonomous teams. It also brings a class of problems that cannot occur inside one process: messages lost or duplicated, services that are slow rather than dead, data that disagrees between copies, and failures in machines you did not know you depended on.

The single most important idea to take away is that distribution is a trade, not an upgrade. Each benefit is bought with latency, consistency, observability and operational effort, and a good architect can say which benefit is being bought, at what price, and why a cheaper option inside a monolith will not do. The fallacies of distributed computing and the arithmetic of synchronous call chains in the first section are the tools for pricing that trade before committing to it.

How the sections fit together

The chapter moves from why to how. Section 6.1 sets out the reasons to distribute, the eight fallacies, partial failure and the costs, and shows with a worked example how five services that each meet 99.9% availability give a request path of only about 99.5%. It ends by revisiting the architecture quantum, which explains why synchronous calls bind separately deployed services together.

The next three sections are the main distributed styles, each treated like the styles in Chapter 5: definition and origin, a diagram, how it works, an example, a characteristics table, when to use it and the usual anti-patterns. Section 6.2 covers service-based architecture, a pragmatic middle ground of a few coarse domain services often sharing a database, and the classic service-oriented architecture of enterprise service buses and canonical models, including why it fell out of favour. Section 6.3 covers microservices: services aligned to bounded contexts, independent deployability, database per service, supporting patterns such as API gateways and service meshes, how to decide granularity, and the distributed monolith and other anti-patterns. Section 6.4 covers event-driven architecture: events and commands, broker and mediator topologies, Kafka's partitions and consumer groups, delivery guarantees and idempotent consumers.

The second half turns to the mechanisms every distributed style depends on. Section 6.5 compares synchronous and asynchronous communication and the coupling each creates, and covers REST, gRPC, GraphQL and messaging, API design practices, versioning and contract testing. Section 6.6 is about what readers of replicated data can expect: consistency models from linearisability to eventual consistency, the CAP theorem and what it really says, PACELC and quorums. Section 6.7 explains why two-phase commit is avoided between services and how sagas, compensating transactions and the transactional outbox keep business processes correct without one. Section 6.8 closes with two styles for particular load profiles: serverless functions, which scale to zero and bill per invocation, and space-based architecture, which keeps data in memory to survive extreme spikes such as a ticket on-sale.

Running examples and how to read the chapter

Two examples recur. The food-delivery platform from earlier chapters (customers, restaurants, couriers, payments) shows ordinary distributed design: it appears as five domain services, as a set of microservices, as an OrderPlaced event flow and as an order saga. A ticketing system selling seats for a stadium tour shows what changes under extreme, spiky load, where tens of thousands of people want the same few seats at the same second.

The chapter is rated intermediate to advanced. It assumes Chapters 0 to 5, in particular availability in series and parallel (Chapter 2), coupling and Conway's law (Chapter 3), and the architecture quantum, modular monolith and bounded contexts (Chapter 5). Beginners can read each section's opening summary and the 'If you are new to this' boxes first. Experienced engineers will find the precision where it matters: what at-least-once delivery implies for every consumer, what 'exactly once' does and does not mean, and why eventual consistency must be designed for rather than tolerated.

What to carry forward

Three habits run through every section. First, count synchronous dependencies, not services: the number of things that must all be working at the same moment for a user's request to succeed decides availability and latency. Second, assume messages are lost, delayed, duplicated and reordered, and design receivers to be idempotent. Third, decide who owns each piece of data, because ownership decides where transactions are possible and where consistency must be managed across services. Chapter 7 develops that third habit into a full treatment of data architecture.

The 8 sections

6.1 · Intermediate · 24 minWhy distributeThe real reasons to split a system across machines, the eight fallacies that make distribution harder than it looks, partial failure, the costs, and the arithmetic of synchronous call chains.Read →6.2 · Intermediate · 22 minService-based and SOACoarse-grained domain services sharing a database, the enterprise service bus era of SOA and why it faded, how microservices differ, and when service-based architecture is the pragmatic middle ground.Read →6.3 · Advanced · 26 minMicroservicesWhat microservices are according to Lewis and Fowler, bounded contexts, independent deployability, database per service, gateways and meshes, how to decide granularity, the classic anti-patterns and the organisational price.Read →6.4 · Advanced · 28 minEvent-drivenEvents, commands and messages; broker and mediator topologies; Fowler's four event patterns; how Kafka's partitions, offsets and consumer groups work; delivery guarantees, idempotent consumers, schemas and dead-letter queues.Read →6.5 · Intermediate · 30 minCommunication and APIsHow services talk: the coupling created by synchronous and asynchronous communication, REST and HTTP semantics, gRPC, GraphQL and messaging, and the API design practices that let interfaces evolve without breaking consumers.Read →6.6 · Advanced · 30 minCAP and consistencyWhat consistency means for replicated data: the models from linearisable to eventual, what the CAP theorem really says and what it does not, PACELC's everyday latency trade-off, quorum arithmetic and choosing consistency per use case.Read →6.7 · Advanced · 30 minSagasHow to keep data consistent when one business action spans several services: two-phase commit and why it is avoided, sagas with compensations, choreography and orchestration, isolation countermeasures, the transactional outbox and idempotent receivers.Read →6.8 · Intermediate · 28 minServerless and space-basedTwo opposite answers to capacity: serverless functions and managed back ends that scale to zero and bill per use, and space-based architecture that serves extreme peaks from replicated memory with the database off the hot path.Read →

Chapter test

Test your understanding of Chapter 6

Optional: 20 multiple-choice questions and 2 short written answers, drawn afresh from a bank of 72 questions. Pass mark 80%. Passing every chapter test, then the final assessment, earns the Be Wise Certificate of Completion.

Take the Chapter 6 test in the app

Further reading