Tags: microservices, distributed-systems, api-gateway, event-driven, docker, kubernetes
Level: intermediate
TL;DR: Architettura a servizi autonomi e debolmente accoppiati, organizzati attorno a capacità di business con database dedicato per servizio.
Servizi autonomi deployabili e scalabili in modo indipendente.
Database-per-service per garantire il disaccoppiamento dei dati.
Comunicazione sincrona via REST o gRPC tra confini di servizio.
Comunicazione asincrona guidata da eventi con message broker.
Bounded Context da Domain-Driven Design per definire i confini.
API Gateway come punto unico di ingresso per i client esterni.
Service Discovery per la localizzazione dinamica delle istanze.
Circuit Breaker per prevenire guasti a cascata nella rete.
Tracing distribuito per seguire il ciclo di vita delle richieste.
Eventual consistency per la sincronizzazione tra domini diversi.
Q: Come gestisci le transazioni distribuite tra più microservizi?R: Evito il two-phase commit e implemento il pattern Saga, preferendo coreografia su event bus o orchestrazione con transazioni compensative.
Q: Quando conviene passare da un monolito ai microservizi?R: Quando la complessità del dominio e la dimensione dei team creano colli di bottiglia su deploy indipendenti e scalabilità selettiva.
Q: Come si evita la rottura dei contratti API tra servizi?R: Introduco consumer-driven contract testing e policy rigorose di versionamento semantico delle API evitando breaking change retroattive.
Condivisione dello stesso database relazionale tra microservizi multipli.
Microservizi troppo granulari che generano un distributed monolith ingestibile.
Comunicazioni a cascata sincrone che moltiplicano la latenza complessiva.
Mancanza di tracing distribuito centralizzato durante incidenti in produzione.
Mancata gestione dei fallimenti parziali e assenza di timeout configurati.
// Pattern Circuit Breaker minimale per chiamate HTTP remote
enum State { Closed, Open, HalfOpen }
class CircuitBreaker {
private state = State.Closed;
private failures = 0;
constructor(private threshold = 5, private timeoutMs = 10000) {}
async execute<T>(action: () => Promise<T>): Promise<T> {
if (this.state === State.Open) {
throw new Error("Circuit breaker open: request rejected");
}
try {
const result = await action();
this.failures = 0;
this.state = State.Closed;
return result;
} catch (err) {
this.failures++;
if (this.failures >= this.threshold) {
this.state = State.Open;
setTimeout(() => { this.state = State.HalfOpen; }, this.timeoutMs);
}
throw err;
}
}
}
[ ] Pattern Saga orchestrata rispetto a Saga coreografata
[ ] Implementazione pratica di Outbox Pattern con Debezium
[x] Ruolo e responsabilità principali dell'API Gateway
[x] Principi base del Domain-Driven Design e Bounded Context