Guida ai pattern: microservizi e design pattern¶
Una traccia semplice per capire cosa è un pattern, che problema risolve e quando usarlo. Ogni pattern ha la stessa struttura: una frase, il problema, come funziona (una vignetta con lo scenario e un diagramma tecnico, entrambi in Mermaid), quando usarlo, quando no, un esempio e i pattern correlati.
Dominio usato in tutti gli esempi: un e-commerce con i servizi Ordini, Pagamenti, Magazzino, Notifiche, Catalogo.
Come leggere la guida¶
- Hai un problema concreto? Parti dalla cheat sheet qui sotto.
- Vuoi studiare una categoria? Apri il capitolo: ogni capitolo inizia con una tabella riassuntiva e finisce con un flowchart
Come scegliere. - Vuoi approfondire i design pattern con analogie e codice in più linguaggi: refactoring.guru/design-patterns.
Mappa¶
flowchart LR
subgraph ms["🏗️ Pattern per microservizi"]
c1["📡 01 Comunicazione"]
c2["🗄️ 02 Dati e transazioni"]
c3["🛡️ 03 Resilienza"]
c4["🧩 04 Decomposizione e migrazione"]
c5["🔭 05 Osservabilità e rilascio"]
end
subgraph dp["🧱 Design pattern (GoF)"]
d1["🏭 01 Creazionali"]
d2["🔗 02 Strutturali"]
d3["🔄 03 Comportamentali"]
end
c1 -->|"come si parlano i servizi"| c2
c2 -->|"come restano coerenti"| c3
c3 -->|"come sopravvivono ai guasti"| c4
c4 -->|"come si tagliano i confini"| c5
d1 --> d2 --> d3
Capitoli¶
Pattern per microservizi¶
| Capitolo | Di cosa parla | Pattern |
|---|---|---|
| 01 Comunicazione | Come i servizi si chiamano fra loro, in sincrono e in asincrono | API Gateway, BFF, Service Discovery, Request-Reply, Pub/Sub, Message Queue, Fan-out/Fan-in, Scatter-Gather, Aggregator, Pipeline |
| 02 Dati e transazioni | Come tenere i dati coerenti senza transazioni condivise | Database per Service, Transactional Outbox, Idempotent Consumer, Saga, CQRS, Event Sourcing, CDC, 2PC |
| 03 Resilienza | Come sopravvivere a rete lenta, servizi giù e picchi | Timeout, Retry, Circuit Breaker, Bulkhead, Rate Limiting, Fallback, DLQ, Health Check, Load Shedding |
| 04 Decomposizione e migrazione | Dove tagliare i confini e come uscire da un monolite | Business Capability, Subdomain, Strangler Fig, ACL, Branch by Abstraction, Parallel Run, Sidecar, Ambassador, Service Mesh |
| 05 Osservabilità e rilascio | Come capire cosa succede in produzione e rilasciare senza paura | Log Aggregation, Correlation ID, Tracing, Metrics, Config esterna, Chassis, Feature Toggle, Blue/Green, Canary, Rolling, Contract Testing |
Design pattern (GoF)¶
| Capitolo | Di cosa parla | Pattern |
|---|---|---|
| 01 Creazionali | Come creare oggetti senza legarsi alle classi concrete | Factory Method, Abstract Factory, Builder, Prototype, Singleton |
| 02 Strutturali | Come comporre oggetti in strutture più grandi e flessibili | Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy |
| 03 Comportamentali | Come gli oggetti comunicano e si dividono le responsabilità | Chain of Responsibility, Command, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor |
Cheat sheet: dal problema al pattern¶
Microservizi¶
| Ho questo problema | Pattern | Capitolo |
|---|---|---|
| I client devono conoscere e chiamare troppi servizi | API Gateway | 01 |
| Web, mobile e partner vogliono dati diversi dalla stessa API | Backend for Frontend | 01 |
| Gli indirizzi delle istanze cambiano di continuo | Service Discovery | 01 |
| Serve una risposta a un'operazione lenta senza bloccare il chiamante | Request-Reply asincrono | 01 |
| Un evento interessa a molti servizi che il produttore non conosce | Publish/Subscribe | 01 |
| Troppi lavori per un solo consumer, voglio scalare aggiungendo istanze | Message Queue / Competing Consumers | 01 |
| Un lavoro grande va spezzato in parallelo e poi ricomposto | Fan-out / Fan-in | 01 |
| Servono risposte da più fonti entro un tempo limite | Scatter-Gather | 01 |
| Una pagina ha bisogno di dati da più servizi | Aggregator / API Composition | 01 |
| Un'elaborazione ha più stadi indipendenti in sequenza | Chain / Pipeline | 01 |
| I servizi sono accoppiati dallo stesso schema del database | Database per Service | 02 |
| Devo scrivere sul DB e pubblicare un evento in modo atomico | Transactional Outbox | 02 |
| Lo stesso messaggio arriva due volte e viene elaborato due volte | Idempotent Consumer | 02 |
| Una transazione di business tocca più servizi, flusso semplice | Saga: coreografia | 02 |
| Una transazione di business tocca più servizi, molti passi e rami | Saga: orchestrazione | 02 |
| Un solo modello serve male sia le scritture che le letture | CQRS | 02 |
| Serve la storia completa dei cambiamenti, audit o replay | Event Sourcing | 02 |
| Voglio pubblicare i cambiamenti del DB senza polling | Transaction Log Tailing / CDC | 02 |
| Una chiamata lenta blocca il chiamante per sempre | Timeout | 03 |
| Errori temporanei fanno fallire operazioni che riproverebbero bene | Retry con backoff e jitter | 03 |
| Continuo a chiamare un servizio già morto | Circuit Breaker | 03 |
| Una dipendenza lenta consuma tutte le risorse condivise | Bulkhead | 03 |
| Troppe richieste travolgono un servizio | Rate Limiting | 03 |
| Una dipendenza giù rende inutile l'intera pagina | Fallback | 03 |
| Un messaggio malformato blocca la coda per tutti | Dead Letter Queue | 03 |
| L'orchestratore manda traffico a istanze rotte | Health Check | 03 |
| Sotto picco il servizio rallenta per tutti | Load Shedding / Backpressure | 03 |
| Non so dove tagliare i confini dei servizi | Business Capability, Subdomain | 04 |
| Riscrivere il monolite in un colpo solo è troppo rischioso | Strangler Fig | 04 |
| Il modello legacy contamina il nuovo servizio | Anti-Corruption Layer | 04 |
| Devo sostituire un componente senza branch lunghi | Branch by Abstraction | 04 |
| Ho paura che il nuovo sistema dia risultati diversi dal vecchio | Parallel Run | 04 |
| Log, TLS e proxy sono duplicati in ogni servizio | Sidecar, Ambassador, Service Mesh | 04 |
| Una libreria condivisa accoppia i servizi di nascosto | Self-contained Service vs Shared Library | 04 |
| I log sono sparsi su decine di container | Log Aggregation | 05 |
| Non riesco a collegare i log di una stessa richiesta | Correlation ID | 05 |
| Non so dove una richiesta perde tempo | Distributed Tracing | 05 |
| Non so se il sistema è sano prima che se ne accorgano gli utenti | Metrics e Golden Signals | 05 |
| Cambiare un parametro richiede una nuova immagine | Externalized Configuration | 05 |
| Ogni servizio reinventa log, health e metriche | Service Template / Chassis | 05 |
| Rilasciare codice vuol dire attivarlo subito per tutti | Feature Toggle | 05 |
| Serve un rollback istantaneo | Blue/Green Deployment | 05 |
| Voglio provare in produzione su pochi utenti | Canary Release | 05 |
| Il rilascio ferma il servizio | Rolling Update | 05 |
| Un cambio di API rompe un consumer senza preavviso | Consumer-Driven Contract Testing | 05 |
Design pattern¶
| Ho questo problema | Pattern | Capitolo |
|---|---|---|
Il codice fa new su classi concrete e non si estende |
Factory Method | 01 |
| Servono famiglie di oggetti coerenti fra loro | Abstract Factory | 01 |
| Costruttori con troppi parametri, molti opzionali | Builder | 01 |
| Copiare oggetti complessi senza conoscerne la classe | Prototype | 01 |
| Serve una sola istanza condivisa | Singleton (preferisci la dependency injection) | 01 |
| Due interfacce incompatibili devono collaborare | Adapter | 02 |
| Due dimensioni di variazione fanno esplodere le sottoclassi | Bridge | 02 |
| Oggetti singoli e gruppi vanno trattati allo stesso modo | Composite | 02 |
| Aggiungere comportamenti (retry, log, cache) senza toccare la classe | Decorator | 02 |
| Un sottosistema complesso espone troppe classi | Facade | 02 |
| Troppi oggetti simili consumano troppa memoria | Flyweight | 02 |
| Controllare o posticipare l'accesso a un oggetto | Proxy | 02 |
| Una richiesta deve passare per più controlli in sequenza | Chain of Responsibility | 03 |
| Un'operazione va salvata, accodata o annullata | Command | 03 |
| Scorrere una collezione senza conoscerne la struttura | Iterator | 03 |
| Troppi oggetti che si parlano direttamente | Mediator | 03 |
| Salvare e ripristinare lo stato di un oggetto | Memento | 03 |
| Avvisare più oggetti quando qualcosa cambia | Observer | 03 |
Il comportamento cambia in base allo stato, con if ovunque |
State | 03 |
| Scegliere un algoritmo fra tanti a runtime | Strategy | 03 |
| Stessa procedura con passi diversi nelle sottoclassi | Template Method | 03 |
| Aggiungere operazioni a una gerarchia senza modificarla | Visitor | 03 |
Ponti fra i due mondi¶
Molti pattern di microservizi sono un design pattern applicato fra processi invece che fra oggetti.
| Design pattern | Versione distribuita |
|---|---|
| Observer | Publish/Subscribe |
| Decorator | Retry, Circuit Breaker come decoratori di un client |
| Facade | API Gateway, Aggregator |
| Adapter | Anti-Corruption Layer |
| Proxy | Sidecar, Ambassador |
| State | Saga: orchestrazione |
| Chain of Responsibility | Chain / Pipeline |
| Command | Message Queue, Event Sourcing |
Struttura dei file¶
mkdocs.yml
docs/
index.md
microservizi/
01-comunicazione.md
02-dati-e-transazioni.md
03-resilienza.md
04-decomposizione-e-migrazione.md
05-osservabilita-e-rilascio.md
design-pattern/
01-creazionali.md
02-strutturali.md
03-comportamentali.md
I diagrammi sono tutti in Mermaid: si vedono su questo sito, su GitHub, in Obsidian e in VS Code con l'anteprima Markdown. Il sito si installa come app dal browser del telefono e funziona anche offline.