SlideShare uma empresa Scribd logo
1 de 46
Baixar para ler offline
@jefrajames
Microservices et cohérence
des données …
Mais on fait comment pour de vrai ?
whoami
{
"name" : "JF James",
"experience_ in_it" : 36,
"company" : "Worldline",
"domain" : "Payment & secured transactions" ,
"skills" : [ " Software architecture" , "Java", "Open Source" , "DevRel" ]
}
Du monolithe aux microservices …
•Définir et borner les services
•Garantir la cohérence d’ensemble des données
Cohérence des données
• Accés aux données d’un service tiers
• Requête multi-services
• Cohérence globale si plusieurs services modifiés
Transaction ACID locale
Module
1
BdD
Begin Commit
Module
2
Module
3
Rollback
Atomicity-Consistency-isolation-Durability
Read Uncommitted
Read Committed
Repeatable Read
Serializable
Transaction ACID locale
• Simplicité de développement
• Performant et scalable
• Eprouvé en production
• Historiquement supporté : base de données SQL, broker JMS
Transaction ACID distribuée
BdD
1
BdD
2
BdD
3
Transaction
Manager
Service
1
Service
2
Service
3
Begin Commit
Rollback
Transaction ACID distribuée
• Simplicité de développement mais …
• Fort couplage technique
• Coût élevé de l’isolation
• Fragilité liée à la coordination synchrone
• Non supporté par NoSQL, Kafka, RabbitMQ, REST, GraphQL, gRPC…
Un point moins ACID SVP
Service
1
BdD
1
Start Confirmation
Service
2
Service
3
BdD
2
BdD
3
LRA/SAGA
ACID locale 1 ACID locale 2 ACID locale 3
Compensation
C’est trop compliqué !
Et les erreurs de compensation ?
Compliqué ?
ACID LRA/SAGA
Erreur technique Rollback global
Service fautif: rollback local
Autres services : code métier exécuté par
action de compensation
Erreur fonctionnelle
Code métier exécuté de
manière spécifique
Service fautif: code métier
Autres services : code métier exécuté par
action de compensation
Limiter les erreurs de compensation
• Isolation des erreurs entre service
• Action de compensation simple, rapide, idempotent
Principes LRA/SAGA
• Des transactions ACID locales
• Une coordination globale légère, faiblement couplée
• Des opérations de compensation explicites
• Perte de l’isolation globale : de ACID à ACD
Les solutions
Ne rien faire
———————————————————————————————————————————————————————————————————————————-
Log + rattrapage à postériori
MicroProfile
GraphQL
Config
Fault
Tolerance
Fallback
Retry
Timeout
Circuit breaker
Bulkhead
OpenAPI
Rest
Client
JWT
API
Jakarta EE Foundation
Health
Metrics
Open
Tracing
Observability
Reactive
Messaging
Reactive
Streams
Context
Propagation
Long Running
Action
Core
JAX-RS CDI JSON
Standalone specs
Un peu de (bonne) lecture
https://microservices.io
https://eventuate.io/
MicroProfile LRA Eventuate SAGA
Origine
OASIS WS-Composite
Application Framework (2006)
SAGA: H. Garcia-Molina & K. Salem
1987 Association for Computing
Eventuate: 2017
Nature Spécification (64 p)
Plateforme Microservices
Open Source
Version
Utilisée
Version 1.0, avril 2021 0.5.1.RELEASE (Quarkus), oct 2022
Implémentations
Quarkus, OpenLiberty,
Helidon, Wildfly, Camel,
SpringBoot (Jersey)
SpringBoot, Micronaut, Quarkus
Modèle de
programmation
Annotations
Orchestration (DSL) ou
Chorégraphie (domain events)
Echange
REST/HTTP
Synchrone
Messaging
Asynchrone
Infrastructure LRA Coordinatorr BdD, Messaging, CDC
En action !
Dispo sur GitHub !
https://github.com/jefrajames/lra-demo
https://github.com/jefrajames/saga-demo
https://github.com/jefrajames/choreo-demo
Démo
21
Holiday
Service
Hotel
Service
Trip
Service
Car
Service
1. Contrôle client
2. Appel Trip
3. Appel Hotel
4. Appel Car
5. Contrôle montant total
a.Contrôle départ
b.Contrôle destination
c.Choix transport & horaire
HolidayBookRequest
PENDING
REJECTED
ACCEPTED
CANCELED
PENDING
REJECTED
ACCEPTED
CANCELED
MicroProfile LRA
MicroProfile LRA Architecture
Holiday
Service
Trip
Service
REST/HTTP
Synchrone
Ports:
• Jeager: 3306
• Postgres: 5432
• LRA Coordinator: 50000
• Trip : 8082
• Holiday : 8080
// Holiday Service
@POST @Path("/book")
@LRA(value = LRA.Type.REQUIRED, end = true,
timeLimit = 2, timeUnit = ChronoUnit.SECONDS,
cancelOn = {Response.Status.INTERNAL_SERVER_ERROR},
cancelOnFamily = {Response.Status.Family.CLIENT_ERROR}
)
public Response book(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId …) {
// Business logic here
}
// Holiday Service
@PUT @Path("/compensate")
@Compensate
public Response compensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
// Required: compensation action here
}
@PUT @Path(«/complete")
@Complete
public Response complete(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
// Optional: clean up actions if any
}
// Trip Service
@POST @Path(« /book")
@LRA(value = LRA.Type.SUPPORTS, end = false)
public Response book(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId …) { … }
@PUT @Path(« /compensate")
@Compensate
public Response compensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) { … }
@PUT @Path(« /complete")
@Complete
public Response complete(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) { … }
Un modèle simple mais …
@LRA @Complete
@Compensate
∆t?
Eventuate
Eventuate Architecture
Holiday
Service
Trip
Service
Ports
Zookeeper : 2181
Kafka : 9092,29092
Kafka GUI : 9088
MySQL-Holiday: 3306
MySQL-Trip: 3308
Cdc-holiday: 9086
Cdc-trip: 9084
Quarkus-Trip : 9082
Quarkus-Holiday : 9080
Kafka howl
kowl
CDC CDC
// Holiday Service DSL-based SAGA definition
private SagaDefinition<HolidayBookSagaData> sagaDefinition =
step()
.invokeLocal(this::create)
.withCompensation(this::reject)
.step()
.invokeLocal(this::checkCustomer)
.step()
.invokeParticipant(this::bookTrip)
.onReply(TripBooked.class, this::handleTripBooked)
.onReply(BookTripFailed.class, this::handleBookTripFailed)
.withCompensation(this::cancelTrip)
.step()
.invokeLocal(this::checkPricing)
.step()
.invokeParticipant(this::confirmTrip)
.step()
.invokeLocal(this::approve)
.build();
Standard
Execution
Compensation
// Trip Service Command Handler
@Transactional
public Message bookTrip(CommandMessage<BookTripCommand> cm) {
BookTripCommand cmd = cm.getCommand();
Trip trip = new Trip(cmd);
tripService.book(trip);
if (trip.businessError != null)
return withFailure(new BookTripFailed(trip.id, trip.businessError));
TripBooked tripBooked = trip.toReply();
return withSuccess(tripBooked);
}
@Transactional
public Message confirmTrip(CommandMessage<ConfirmTripCommand> cm) { … }
@Transactional
public Message cancelTrip(CommandMessage<CancelTripCommand> cm) { … }
Change Data Capture
Publisher Consumer
message
table
CDC
SQL polling Transaction log tailing
Local ACID transaction
CDC
Publish Subscribe
Local ACID transaction
received
message
Business logic Business logic
Base de données Eventuate
Holiday Trip
cdc_monitoring X X
entities X X
events X X
message X X
offset_store X X
received_message X X
Infrastructure X X
saga_instance X
saga_instance_partition X
saga_lock_table X
snapshots X
Benchmark
Quelques chiffres
Lines of
code
Overhead
Response
time ms
Overhead
Monolith ACID local 918 32
REST 1435 1,56 57 1,78
REST + LRA 1495 1,63 126 3,94
Eventuate choreographie 1419 1,55 130 4,06
Eventuate orchestration 1951 2,13 244 7,63
MicroProfile LRA Eventuate SAGA
Composants clés
SPOF potentiels
Narayana CDC, Messaging, BdD
Courbe
d’apprentissage **** ***
Productivité **** ****
Simplicité de
configuration **** ***
Découplage
fonctionnel **** ***
Découplage
technique ** ****
Observabilité *** ****
Généricité *** ****
Roadmap **** ***
Alternatives Apache Camel et Debezium
Apache Camel LRA Module
// action
from("direct:reserveCredit")
.saga()
.propagation(SagaPropagation.MANDATORY)
.compensation("direct:refundCredit")
.transform().header(Exchange.SAGA_LONG_RUNNING_ACTION)
.bean(creditService, "reserveCredit")
.log("Credit ${header.amount} reserved in action ${body}");
// compensation
from("direct:refundCredit")
.transform().header(Exchange.SAGA_LONG_RUNNING_ACTION)
.bean(creditService, "refundCredit")
.log("Credit for action ${body} refunded");
Debezium
Debezium Outbox
Conclusion
En résumé
• Une problématique complexe … des solutions mais pas de miracle !
• Accepter le principe de compensation : c’est possible !
• MicroProfile LRA OK si : « Full REST» (ou Apache CAMEL)
• SAGA chorégraphie OK si : complexité fonctionnelle modérée
• SAGA orchestration OK si : complexité fonctionnelle élevée, transaction
longue durée
Merci
Pour terminer
• Si trop de transaction distribuée : revoir le découpage en service
• Solution minimaliste : tracer les erreurs et compenser en arrière plan
• Des solutions plus avancées existent
• Ne pas négliger les performances et le monitoring
• Actions de compensation simples, rapides et idempotent
Pour aller plus loin
• Mes 2 démos sur GitHub :
• https://github.com/jefrajames/lra-demo
• https://github.com/jefrajames/saga-demo
• Eventuate : le site microservices.io, le site Eventuate et les exemples
• LRA: le blog Narayana, les exemples Quarkus, Open Liberty, Helidon
Pour aller encore plus loin
• Un exemple LRA avec SpringBoot (Jersey) et Axon
• Le module LRA Camel
• Configurer le CDC en transaction log tailing sur PostgreSQL
• Oubtbox Quarkus Extension

Mais conteúdo relacionado

Semelhante a LyonJUG-2023-v1.0.pdf

ToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & AgilitéToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & AgilitéNicolas Deverge
 
Bbl microservices avec vert.x cdi elastic search
Bbl microservices avec vert.x cdi elastic searchBbl microservices avec vert.x cdi elastic search
Bbl microservices avec vert.x cdi elastic searchIdriss Neumann
 
MariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentationMariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentationMariaDB plc
 
Le cloud-in-a-box avec Cloud Platform System (CPS) et Windows Azure Pack
Le cloud-in-a-box avec Cloud Platform System (CPS) et Windows Azure PackLe cloud-in-a-box avec Cloud Platform System (CPS) et Windows Azure Pack
Le cloud-in-a-box avec Cloud Platform System (CPS) et Windows Azure PackMicrosoft Décideurs IT
 
Rouabhi algiers meetup
Rouabhi algiers meetupRouabhi algiers meetup
Rouabhi algiers meetupSamir Rouabhi
 
Open Source et Microsoft Azure, rêve ou réalité ?
Open Source et Microsoft Azure, rêve ou réalité ?Open Source et Microsoft Azure, rêve ou réalité ?
Open Source et Microsoft Azure, rêve ou réalité ?Microsoft
 
Java dans Windows Azure: l'exemple de Jonas
Java dans Windows Azure: l'exemple de JonasJava dans Windows Azure: l'exemple de Jonas
Java dans Windows Azure: l'exemple de JonasMicrosoft
 
Architectures microservices
Architectures microservicesArchitectures microservices
Architectures microservicesRiadh MNASRI
 
.NET Microframework, les joies de l'électronique et du code pour tous
.NET Microframework, les joies de l'électronique et du code pour tous.NET Microframework, les joies de l'électronique et du code pour tous
.NET Microframework, les joies de l'électronique et du code pour tousMicrosoft
 
Retours Devoxx France 2016
Retours Devoxx France 2016Retours Devoxx France 2016
Retours Devoxx France 2016Antoine Rey
 
2008-10-02 Paris - Administration des applications critiques avec SQL Server ...
2008-10-02 Paris - Administration des applications critiques avec SQL Server ...2008-10-02 Paris - Administration des applications critiques avec SQL Server ...
2008-10-02 Paris - Administration des applications critiques avec SQL Server ...Patrick Guimonet
 
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...Publicis Sapient Engineering
 
Orchestrating Docker in production - TIAD Camp Docker
Orchestrating Docker in production - TIAD Camp DockerOrchestrating Docker in production - TIAD Camp Docker
Orchestrating Docker in production - TIAD Camp DockerThe Incredible Automation Day
 

Semelhante a LyonJUG-2023-v1.0.pdf (20)

ToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & AgilitéToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & Agilité
 
Bbl microservices avec vert.x cdi elastic search
Bbl microservices avec vert.x cdi elastic searchBbl microservices avec vert.x cdi elastic search
Bbl microservices avec vert.x cdi elastic search
 
MariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentationMariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentation
 
Le cloud-in-a-box avec Cloud Platform System (CPS) et Windows Azure Pack
Le cloud-in-a-box avec Cloud Platform System (CPS) et Windows Azure PackLe cloud-in-a-box avec Cloud Platform System (CPS) et Windows Azure Pack
Le cloud-in-a-box avec Cloud Platform System (CPS) et Windows Azure Pack
 
Inf208
Inf208Inf208
Inf208
 
Rouabhi algiers meetup
Rouabhi algiers meetupRouabhi algiers meetup
Rouabhi algiers meetup
 
Open Source et Microsoft Azure, rêve ou réalité ?
Open Source et Microsoft Azure, rêve ou réalité ?Open Source et Microsoft Azure, rêve ou réalité ?
Open Source et Microsoft Azure, rêve ou réalité ?
 
Retour d'expérience Minio
Retour d'expérience MinioRetour d'expérience Minio
Retour d'expérience Minio
 
Java dans Windows Azure: l'exemple de Jonas
Java dans Windows Azure: l'exemple de JonasJava dans Windows Azure: l'exemple de Jonas
Java dans Windows Azure: l'exemple de Jonas
 
Architectures microservices
Architectures microservicesArchitectures microservices
Architectures microservices
 
.NET Microframework, les joies de l'électronique et du code pour tous
.NET Microframework, les joies de l'électronique et du code pour tous.NET Microframework, les joies de l'électronique et du code pour tous
.NET Microframework, les joies de l'électronique et du code pour tous
 
The Future of Javascript
The Future of JavascriptThe Future of Javascript
The Future of Javascript
 
The future of JavaScript
The future of JavaScriptThe future of JavaScript
The future of JavaScript
 
Retours Devoxx France 2016
Retours Devoxx France 2016Retours Devoxx France 2016
Retours Devoxx France 2016
 
12-Factor
12-Factor12-Factor
12-Factor
 
Wygday 2008
Wygday 2008Wygday 2008
Wygday 2008
 
2008-10-02 Paris - Administration des applications critiques avec SQL Server ...
2008-10-02 Paris - Administration des applications critiques avec SQL Server ...2008-10-02 Paris - Administration des applications critiques avec SQL Server ...
2008-10-02 Paris - Administration des applications critiques avec SQL Server ...
 
Talk gRPC et Dapr
Talk gRPC et DaprTalk gRPC et Dapr
Talk gRPC et Dapr
 
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services  Par Al...
XebiCon'16 : Choisissez votre style avec Docker & Amazon Web Services Par Al...
 
Orchestrating Docker in production - TIAD Camp Docker
Orchestrating Docker in production - TIAD Camp DockerOrchestrating Docker in production - TIAD Camp Docker
Orchestrating Docker in production - TIAD Camp Docker
 

Mais de Jean-Francois James

Mais de Jean-Francois James (6)

When GenAI meets with Java with Quarkus and langchain4j
When GenAI meets with Java with Quarkus and langchain4jWhen GenAI meets with Java with Quarkus and langchain4j
When GenAI meets with Java with Quarkus and langchain4j
 
Loom promises: be there!
Loom promises: be there!Loom promises: be there!
Loom promises: be there!
 
Boost your APIs with GraphQL
Boost your APIs with GraphQLBoost your APIs with GraphQL
Boost your APIs with GraphQL
 
Tnt 2020-jf-james
Tnt 2020-jf-jamesTnt 2020-jf-james
Tnt 2020-jf-james
 
Talk Oracle Code One 2019
Talk Oracle Code One 2019Talk Oracle Code One 2019
Talk Oracle Code One 2019
 
Boost your API with GraphQL
Boost your API with GraphQLBoost your API with GraphQL
Boost your API with GraphQL
 

LyonJUG-2023-v1.0.pdf

  • 1. @jefrajames Microservices et cohérence des données … Mais on fait comment pour de vrai ?
  • 2. whoami { "name" : "JF James", "experience_ in_it" : 36, "company" : "Worldline", "domain" : "Payment & secured transactions" , "skills" : [ " Software architecture" , "Java", "Open Source" , "DevRel" ] }
  • 3. Du monolithe aux microservices … •Définir et borner les services •Garantir la cohérence d’ensemble des données
  • 4. Cohérence des données • Accés aux données d’un service tiers • Requête multi-services • Cohérence globale si plusieurs services modifiés
  • 5. Transaction ACID locale Module 1 BdD Begin Commit Module 2 Module 3 Rollback
  • 7. Transaction ACID locale • Simplicité de développement • Performant et scalable • Eprouvé en production • Historiquement supporté : base de données SQL, broker JMS
  • 9. Transaction ACID distribuée • Simplicité de développement mais … • Fort couplage technique • Coût élevé de l’isolation • Fragilité liée à la coordination synchrone • Non supporté par NoSQL, Kafka, RabbitMQ, REST, GraphQL, gRPC…
  • 10. Un point moins ACID SVP Service 1 BdD 1 Start Confirmation Service 2 Service 3 BdD 2 BdD 3 LRA/SAGA ACID locale 1 ACID locale 2 ACID locale 3 Compensation
  • 11. C’est trop compliqué ! Et les erreurs de compensation ?
  • 12. Compliqué ? ACID LRA/SAGA Erreur technique Rollback global Service fautif: rollback local Autres services : code métier exécuté par action de compensation Erreur fonctionnelle Code métier exécuté de manière spécifique Service fautif: code métier Autres services : code métier exécuté par action de compensation
  • 13. Limiter les erreurs de compensation • Isolation des erreurs entre service • Action de compensation simple, rapide, idempotent
  • 14. Principes LRA/SAGA • Des transactions ACID locales • Une coordination globale légère, faiblement couplée • Des opérations de compensation explicites • Perte de l’isolation globale : de ACID à ACD
  • 15. Les solutions Ne rien faire ———————————————————————————————————————————————————————————————————————————- Log + rattrapage à postériori
  • 16. MicroProfile GraphQL Config Fault Tolerance Fallback Retry Timeout Circuit breaker Bulkhead OpenAPI Rest Client JWT API Jakarta EE Foundation Health Metrics Open Tracing Observability Reactive Messaging Reactive Streams Context Propagation Long Running Action Core JAX-RS CDI JSON Standalone specs
  • 17. Un peu de (bonne) lecture https://microservices.io https://eventuate.io/
  • 18. MicroProfile LRA Eventuate SAGA Origine OASIS WS-Composite Application Framework (2006) SAGA: H. Garcia-Molina & K. Salem 1987 Association for Computing Eventuate: 2017 Nature Spécification (64 p) Plateforme Microservices Open Source Version Utilisée Version 1.0, avril 2021 0.5.1.RELEASE (Quarkus), oct 2022 Implémentations Quarkus, OpenLiberty, Helidon, Wildfly, Camel, SpringBoot (Jersey) SpringBoot, Micronaut, Quarkus Modèle de programmation Annotations Orchestration (DSL) ou Chorégraphie (domain events) Echange REST/HTTP Synchrone Messaging Asynchrone Infrastructure LRA Coordinatorr BdD, Messaging, CDC
  • 20. Dispo sur GitHub ! https://github.com/jefrajames/lra-demo https://github.com/jefrajames/saga-demo https://github.com/jefrajames/choreo-demo
  • 21. Démo 21 Holiday Service Hotel Service Trip Service Car Service 1. Contrôle client 2. Appel Trip 3. Appel Hotel 4. Appel Car 5. Contrôle montant total a.Contrôle départ b.Contrôle destination c.Choix transport & horaire HolidayBookRequest PENDING REJECTED ACCEPTED CANCELED PENDING REJECTED ACCEPTED CANCELED
  • 23. MicroProfile LRA Architecture Holiday Service Trip Service REST/HTTP Synchrone Ports: • Jeager: 3306 • Postgres: 5432 • LRA Coordinator: 50000 • Trip : 8082 • Holiday : 8080
  • 24. // Holiday Service @POST @Path("/book") @LRA(value = LRA.Type.REQUIRED, end = true, timeLimit = 2, timeUnit = ChronoUnit.SECONDS, cancelOn = {Response.Status.INTERNAL_SERVER_ERROR}, cancelOnFamily = {Response.Status.Family.CLIENT_ERROR} ) public Response book(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId …) { // Business logic here }
  • 25. // Holiday Service @PUT @Path("/compensate") @Compensate public Response compensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) { // Required: compensation action here } @PUT @Path(«/complete") @Complete public Response complete(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) { // Optional: clean up actions if any }
  • 26. // Trip Service @POST @Path(« /book") @LRA(value = LRA.Type.SUPPORTS, end = false) public Response book(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId …) { … } @PUT @Path(« /compensate") @Compensate public Response compensate(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) { … } @PUT @Path(« /complete") @Complete public Response complete(@HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) { … }
  • 27. Un modèle simple mais … @LRA @Complete @Compensate ∆t?
  • 29. Eventuate Architecture Holiday Service Trip Service Ports Zookeeper : 2181 Kafka : 9092,29092 Kafka GUI : 9088 MySQL-Holiday: 3306 MySQL-Trip: 3308 Cdc-holiday: 9086 Cdc-trip: 9084 Quarkus-Trip : 9082 Quarkus-Holiday : 9080 Kafka howl kowl CDC CDC
  • 30. // Holiday Service DSL-based SAGA definition private SagaDefinition<HolidayBookSagaData> sagaDefinition = step() .invokeLocal(this::create) .withCompensation(this::reject) .step() .invokeLocal(this::checkCustomer) .step() .invokeParticipant(this::bookTrip) .onReply(TripBooked.class, this::handleTripBooked) .onReply(BookTripFailed.class, this::handleBookTripFailed) .withCompensation(this::cancelTrip) .step() .invokeLocal(this::checkPricing) .step() .invokeParticipant(this::confirmTrip) .step() .invokeLocal(this::approve) .build(); Standard Execution Compensation
  • 31. // Trip Service Command Handler @Transactional public Message bookTrip(CommandMessage<BookTripCommand> cm) { BookTripCommand cmd = cm.getCommand(); Trip trip = new Trip(cmd); tripService.book(trip); if (trip.businessError != null) return withFailure(new BookTripFailed(trip.id, trip.businessError)); TripBooked tripBooked = trip.toReply(); return withSuccess(tripBooked); } @Transactional public Message confirmTrip(CommandMessage<ConfirmTripCommand> cm) { … } @Transactional public Message cancelTrip(CommandMessage<CancelTripCommand> cm) { … }
  • 32. Change Data Capture Publisher Consumer message table CDC SQL polling Transaction log tailing Local ACID transaction CDC Publish Subscribe Local ACID transaction received message Business logic Business logic
  • 33. Base de données Eventuate Holiday Trip cdc_monitoring X X entities X X events X X message X X offset_store X X received_message X X Infrastructure X X saga_instance X saga_instance_partition X saga_lock_table X snapshots X
  • 35. Quelques chiffres Lines of code Overhead Response time ms Overhead Monolith ACID local 918 32 REST 1435 1,56 57 1,78 REST + LRA 1495 1,63 126 3,94 Eventuate choreographie 1419 1,55 130 4,06 Eventuate orchestration 1951 2,13 244 7,63
  • 36. MicroProfile LRA Eventuate SAGA Composants clés SPOF potentiels Narayana CDC, Messaging, BdD Courbe d’apprentissage **** *** Productivité **** **** Simplicité de configuration **** *** Découplage fonctionnel **** *** Découplage technique ** **** Observabilité *** **** Généricité *** **** Roadmap **** ***
  • 38. Apache Camel LRA Module // action from("direct:reserveCredit") .saga() .propagation(SagaPropagation.MANDATORY) .compensation("direct:refundCredit") .transform().header(Exchange.SAGA_LONG_RUNNING_ACTION) .bean(creditService, "reserveCredit") .log("Credit ${header.amount} reserved in action ${body}"); // compensation from("direct:refundCredit") .transform().header(Exchange.SAGA_LONG_RUNNING_ACTION) .bean(creditService, "refundCredit") .log("Credit for action ${body} refunded");
  • 42. En résumé • Une problématique complexe … des solutions mais pas de miracle ! • Accepter le principe de compensation : c’est possible ! • MicroProfile LRA OK si : « Full REST» (ou Apache CAMEL) • SAGA chorégraphie OK si : complexité fonctionnelle modérée • SAGA orchestration OK si : complexité fonctionnelle élevée, transaction longue durée
  • 43. Merci
  • 44. Pour terminer • Si trop de transaction distribuée : revoir le découpage en service • Solution minimaliste : tracer les erreurs et compenser en arrière plan • Des solutions plus avancées existent • Ne pas négliger les performances et le monitoring • Actions de compensation simples, rapides et idempotent
  • 45. Pour aller plus loin • Mes 2 démos sur GitHub : • https://github.com/jefrajames/lra-demo • https://github.com/jefrajames/saga-demo • Eventuate : le site microservices.io, le site Eventuate et les exemples • LRA: le blog Narayana, les exemples Quarkus, Open Liberty, Helidon
  • 46. Pour aller encore plus loin • Un exemple LRA avec SpringBoot (Jersey) et Axon • Le module LRA Camel • Configurer le CDC en transaction log tailing sur PostgreSQL • Oubtbox Quarkus Extension