Architettura a microservizi con CQRS, Event Sourcing e Axon Framework
Pensare lo sviluppo di un’architettura basata su microservizi non è banale. Se, inoltre, il sistema deve gestire in modo efficiente l’energia elettrica, come nel caso delle comunità energetiche, la complessità aumenta ulteriormente.
Negli ultimi anni, le architetture event-driven sono diventate sempre più popolari per affrontare scenari in cui è fondamentale garantire scalabilità, resilienza e tracciabilità delle modifiche di stato. Tra i pattern più utilizzati in questo contesto troviamo CQRS (Command Query Responsibility Segregation) ed Event Sourcing (ES). Ma perché scegliere questa combinazione?
Un po’ di storia: Perché CQRS + Event Sourcing?
CQRS nasce dall’idea di separare i modelli di lettura (query) e scrittura (comandi) per ottimizzare le prestazioni e ridurre la complessità nei sistemi transazionali. Event Sourcing, invece, viene adottato per mantenere la cronologia completa delle modifiche di stato attraverso eventi immutabili, facilitando audit, rollback e ripristino dello stato del sistema.
L’unione di CQRS ed Event Sourcing permette di costruire sistemi altamente scalabili, con una gestione più chiara della concorrenza e della persistenza dei dati.
CQRS: Separare comandi e query
Nel modello tradizionale, letture e scritture spesso condividono lo stesso modello dati, causando inefficienze e problemi di scalabilità. CQRS propone di separare questi due aspetti:
- Comandi (Command): rappresentano azioni che modificano lo stato del sistema, come EffettuareUnPagamento o ConfermareOrdine.
- Query: recuperano dati dallo stato attuale del sistema senza modificarlo.
Questa separazione consente di ottimizzare la lettura e la scrittura in modo indipendente, migliorando le performance e riducendo i conflitti di concorrenza.
Event Sourcing: memorizzare lo stato attraverso eventi
A differenza dei database tradizionali, che sovrascrivono i dati aggiornati, il pattern Event Sourcing memorizza ogni modifica di stato sotto forma di eventi immutabili.
Un evento è generato in risposta a un comando valido e viene salvato in un Event Store, che funge da “fonte di verità” del sistema. Per ottenere lo stato corrente di un’entità (ad esempio un ordine), è sufficiente rilanciare tutti gli eventi associati a essa.
Di seguito un esempio.
- Un comando EffettuaOrdine viene inviato a un aggregato.
- Se il comando è valido, viene generato un evento OrdineEffettuato e salvato nell’Event Store.
- Lo stato dell’aggregato viene aggiornato in base agli eventi applicati.
- Altre parti del sistema possono reagire all’evento in modo asincrono.
Benefici di CQRS + Event Sourcing
- Scalabilità: separare lettura e scrittura consente di ottimizzare e scalare in modo indipendente.
- Storico completo: ogni cambiamento è tracciato, permettendo audit e debug avanzati.
- Resilienza: lo stato può essere ricostruito in qualsiasi momento semplicemente riproducendo gli eventi.
- Facilità di integrazione con sistemi reattivi ed event-driven.
Esempio di applicazione: un caso studio in ambito Energy
Il caso studio che tratteremo nei prossimi paragrafi riguarda la collaborazione di Intré con un cliente nell’ambito del progetto PlatOne. Intré ha utilizzato le soluzioni di AxonIQ, in particolare Axon Framework, per lo sviluppo di un simulatore in ambito Energy.
Il contesto: Progetto PlatOne
Il progetto europeo PlatOne (PLATform for Operation of distribution Networks), finanziato dall’Unione Europea nell’ambito di Horizon 2020, punta a sviluppare e testare soluzioni tecnologiche avanzate per abilitare la flessibilità energetica in un mercato aperto e inclusivo. Il consorzio affronta la sfida di gestire le crescenti congestioni di rete causate dalla diffusione di fonti rinnovabili a generazione variabile e dall’elettrificazione di riscaldamento, raffreddamento e mobilità.
Il prodotto software realizzato
Intré ha supportato il cliente nella progettazione e nello sviluppo di un microservizio strategico per la gestione delle sessioni di calcolo in ambito energetico. L’obiettivo era creare un’applicazione in grado di simulare scenari futuri sulla rete elettrica esistente — dalle cabine primarie e secondarie fino ai contatori domestici — per individuare eventuali criticità.
Sulla base della situazione del calcolo data, il software intercetta possibili problemi elettrici, per esempio sovraccarichi di tensione o di corrente.
L’identificazione delle criticità consente di gestire in maniera più efficiente la rete elettrica di una città, permettendo anche di “riutilizzare” la corrente presente per indirizzarla dove necessario al posto di comprarla dal GME (Gestori Mercati Energetici).
Coordinare simulazioni complesse con un’architettura CQRS + Event Sourcing
Uno degli elementi chiave di un sistema basato su CQRS + ES è la capacità di coordinare processi complessi in modo affidabile e scalabile. Il sistema, completamente asincrono, ha reso naturale l’adozione di CQRS per gestire il flusso di lavoro e monitorare l’avanzamento delle simulazioni. I comandi vengono utilizzati per avviare, controllare e completare le sessioni di calcolo, mentre gli eventi tracciano ogni cambiamento di stato.
L’Event Sourcing ha permesso di registrare ogni fase della simulazione, consentendo la ricostruzione della sequenza di dati in caso di errori o necessità di audit. Inoltre, la definizione di comandi ed eventi specifici per ogni tipologia di calcolo ha reso più semplice l’estensione del sistema a nuove funzionalità.
L’adozione di Axon Framework
Uno degli aspetti cruciali nell’implementazione di CQRS + ES è la gestione della complessità legata alla sequenzialità degli eventi e alla propagazione dei comandi. Per semplificare questo processo, è stato adottato Axon Framework, una soluzione open-source per Java e Spring Boot.
Axon Framework fornisce un’infrastruttura completa per gestire aggregati, comandi, eventi e query all’interno di un’architettura basata su CQRS + ES. Il framework include anche un Command Bus chiamato Disruptor Command Bus, che offre esecuzione asincrona e alte performance, riducendo i tempi di calcolo complessivi.
La società AxonIQ, che sviluppa il framework, ha rilasciato anche prodotti complementari come Axon Server e AxonIQ Console, che semplificano ulteriormente la gestione dei sistemi basati su eventi.
Nel caso specifico del cliente, è stato utilizzato Axon Framework preferendo l’implementazione del salvataggio degli eventi su database e sfruttando le capacità avanzate del Disruptor Command Bus di parallelizzare l’invio dei comandi verso l’aggregato. Questo ha garantito alte prestazioni e tempi di esecuzione ridotti, fondamentali per ottimizzare i processi di calcolo energetico gestiti dalla piattaforma.
Conclusioni
Per il team di sviluppo, l’adozione di “Axon Framework” è stata una scelta naturale. L’integrazione con spring-boot ha automatizzato la maggior parte degli oggetti necessari, permettendo ai developer di concentrarsi sulla definizione del modello dati (Aggregato), dei comandi e degli eventi.
Grazie a CQRS + Event Sourcing e a strumenti come “Axon Framework”, è stato possibile sviluppare un sistema scalabile, affidabile e facilmente estendibile, ottimizzando al tempo stesso le prestazioni e la gestione delle sessioni di calcolo nella piattaforma DSOTP.