Migliorare l’affidabilità dei microservizi – parte 1: Two Phase Commit
Ciao a tutti! Oggi parleremo un po’ di come possiamo fare per migliorare l’affidabilità della comunicazione fra microservizi. Questo è il primo articolo della serie e ci focalizzeremo sulla tecnica del Two-Phase-Commit.
È passato un po’ dal mio ultimo articolo, questo è il primo che scrivo da quando mi sono trasferito a Montreal per lavorare con una software house del posto, Fiska.
Supponiamo di star sviluppando un’applicazione a microservizi e di doverli far comunicare in qualche modo. Un servizio isolato non è particolarmente utile, bisogna quasi sempre condividere dei dati con il resto del sistema. Magari stiamo lavorando al prossimo Amazon o Netflix, chi lo sa!
<figcaption>giusto un paio di microservizi.</figcaption></figure>
Cerchiamo di fare un esempio semplice. Immaginiamo il caso di un ordine piazzato su un ecommerce. Il microservizio degli Ordini riceve la richiesta, salva i dati nel suo persistence layer e successivamente ha bisogno di informare tutti gli altri servizi interessati. Ad esempio un microservizio per le Notifiche che deve inviare email al cliente e agli amministratori.
Ovviamente non vogliamo che le email vengano inviate se incappiamo in qualche errore durante il salvataggio dell’ordine.
Un approccio possibile è il famoso Two-Phase-Commit (detto anche 2PC):
<figcaption>2 Phase Commit</figcaption></figure>
Come potete facilmente immaginare si tratta di un processo a 2 step:
- Un servizio Coordinatore chiede a tutti i partecipanti se sono pronti ad effettuare il commit della transazione. Questi possono rispondere si o no. Nel caso anche un solo servizio risponda no (oppure avviene un timeout o qualunque altro errore), l’intera transazione viene automaticamente annullata.
- Se tutti i partecipanti rispondono si, il Coordinatore invia a tutti il comando di Commit e si mette in attesa per la conferma.
È un meccanismo perfettamente oliato e funzionante, anche se non esente da difetti. Prima di tutto c’è un costo intrinseco di performance da pagare in quanto mettiamo tutti gli attori in attesa diverse volte.
Oltretutto, se il Coordinatore fallisce per qualunque motivo all’inizio della Fase 2, tutti gli altri servizi restano bloccati in una sorta di limbo.
Non fraintendetemi, 2PC è un buon approccio ma come tutti gli altri attrezzi a nostra disposizione è molto importante sapere quando e come sfruttarlo. Per esempio è particolarmente utile quando bisogna replicare dati fra nodi di un cluster di database.
Tornando al nostro ecommerce, nel prossimo articolo vedremo come possiamo invece usare il design pattern Outbox per inviare in maniera sicura un messaggio fra microservizi quando viene piazzato un ordine.
Au-revoir!