Aller au contenu
REJOIGNEZ-NOUS
Rechercher
Fermer ce champ de recherche.

FR

|

EN

ARTICLE

Architecture microservice et cohérence des données

Évoluer du monolithe vers les microservices n’est pas un long fleuve tranquille… Les challenges ne manquent pas. L’un d’entre eux, et non des moindres, est la cohérence des données. Un des principes de base est que chaque service possède sa propre base de données. Quand une transaction métier invoque plusieurs services, on ne peut donc plus compter sur les bonnes vieilles transactions ACID des serveurs SQL.

Résumé de la conférence donnée par Jean-François James lors du devfest 2022

Dans un modèle classique de monolithe où plusieurs modules partagent la même base de données, le modèle ACID permet de garder une cohérence dans les données avec une simple transaction.

Mais comment maintenir ce niveau de cohérence dans une architecture microservice où chaque application possède sa BDD et son propre jeu de données ?

Microservice

Plusieurs solutions existent :

  • Transaction ACID locale et création de traitements de corrections à passages réguliers
  • Two-phase Commit qui maintient à la fois une transaction locale par application et une transaction globale pour gérer la coordination de toutes les applications. Ce système génère des transactions très longues et n’est supporté que par les BDD relationnelles
  • Utilisation de LRA/SAGA pour gérer des flux de compensation

LRA/SAGA est un pattern d’architecture qui permet de gérer des évènements de compensation sur plusieurs applications. Lorsque l’une des transactions locales rencontre une erreur (technique ou métier) sur l’un des différents microservices, un flux de compensation est lancé pour annuler les traitements dans les autres microservices. La définition de l’action de compensation est à la charge du développeur (recréditation de compte, annulation de réservation, …)

Les principes de fonctionnement de ce pattern d’architecture reposent sur :

  • Des transactions locales
  • Une coordination globale légère, faiblement couplée
  • Des opérations de compensation explicites (définies par le développeur)
  • Perte de l’isolation globale : de ACID à ACD (pas besoin d’attendre la fin de toutes les transactions)

Plusieurs solutions implémentent ce pattern, notamment :

  • Microprofile LRA
  • Eventuate SAGA

Microprofile LRA

Microprofile est un ensemble de spécifications permettant d’améliorer l’expérience de développement en JEE. Microprofile LRA est la spécification de la méthode permettant de maintenir une cohérence des données en se basant sur LRA.

OrigineOasis WS-Composite Application Framework (2006)
NatureSpécification (64 p)
Version1.0, avril 2021
ImplémentationsQuarkus, OpenLiberty, Helidon, Wildfly, Camel EIP
Modèle de programmationAnnotations
EchangeREST/HTTP Synchrone
InfrastructureLRA Coordinator

Architecture

LRA nécessite le déploiement d’un LRA coordinator (Narayana), qui coordonne les transactions des différentes applications et déclenche les traitements de compensation.
Un en-tête HTTP lraid est ajouté aux requêtes afin de relier les requêtes sur lesquelles doivent être lancées les flux de compensation.

Implémentation

Le paramétrage de LRA et des méthodes de compensation/complétion se fait grâce à des annotations. La configuration du service Holiday peut être par exemple :

@LRA(value = LRA.Type.REQUIRED, end = true, timeLimit = 2, timeUnit = ChronoUnit.SECONDS, 
cancelOn = {Response.Status.INTERNAL_SERVER_ERROR},
cancelOnFamily = { Response.Status.Family.CLIENT_ERROR })
@POST
@Path("/book")
public Response book(@Parameter(description = "LRA id (automatically provided)", hidden = true) @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
    // ...
}

@Compensate
@Path("/compensate")
@PUT
public Response compensate(@Parameter(description = "LRA id (automatically provided)", hidden = true) @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
    // ...
}

@Compensate
@Path("/complete")
@PUT
public Response complete(@Parameter(description = "LRA id (automatically provided)", hidden = true) @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
    // ...
}

La méthode compensate peut être appelée de manière concurrente à l’un des services distants (attention à gérer les cas de collisions dans le code). Il est alors recommandé de persister en base les lraids de transaction qui sont en erreur, afin de lancer les traitements de compensation si l’un des services distants a continué de s’exécuter et d’enregistrer des données après le lancement de compensate.
Si nous reprenons l’exemple, la configuration du service Trip appelé par le service Holiday est la suivante :

@LRA(value = LRA.Type.SUPPORTS, end = false)
@POST
@Path("/book")
public Response book(@Parameter(description = "LRA id (automatically provided)", hidden = true) @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
    // ...
}

@Compensate
@Path("/compensate")
@PUT
public Response compensate(@Parameter(description = "LRA id (automatically provided)", hidden = true) @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
    // ...
}

@Compensate
@Path("/complete")
@PUT
public Response complete(@Parameter(description = "LRA id (automatically provided)", hidden = true) @HeaderParam(LRA_HTTP_CONTEXT_HEADER) String lraId) {
    // ...
}

SAGA Eventuate

SAGA Eventuate est un framework permettant la coordination de données entre des microservices JAVA utilisant JDBC/JPA.

OrigineSAGA: 1987 Eventuate: 2047
NaturePlateforme Microservices Open SOurce
Version0.30.0 (Quarkus), avril 2021
ImplémentationsSpring, Micronaut, Quarkus
Modèle de programmationOrchestration (DSL) ou Chorégraphie (domain events)
EchangeMessaging Asynchrone
InfrastructureCDC, Kafka, PostgreSQL

Architecture

Eventuate nécessite un comportement asynchrone, d’où l’utilisation de Kafka dans l’exemple. Les CDC sont les éléments qui permettent de gérer le déclenchement d’une compensation. Les CDC étant développés à partir de Spring Boot, il est possible d’accéder aux metrics de ces briques avec actuator.

Implémentation

La configuration des services avec Eventuate se fait fonctionnellement via la définition d’étapes à suivre. Si on reprend l’exemple de Holiday, les étapes à suivre par le service seraient :

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();

On peut lire de haut en bas le déroulement normal des actions à effectuer et de bas en haut l’ordre des actions pour annuler le traitement.
Dans le code métier des fonctions, l’appel aux méthodes withFailure et withSuccess permet de retourner le résultat et donc le déclenchement ou non d’une compensation.
Les différentes SAGA sont persistées dans des tables dédiées à Eventuate.
Le CDC scrute alors les logs de transactions locales du publisher (qui envoie le résultat de sa fonction) enregistrées en base et les envoie au consumer (qui peut lancer le traitement de compensation).

Conclusion

Pour résumer, Microprofile et Eventuate sont équivalents en terme de nombre de lignes de code. Cependant, on peut noter que Eventuate demande beaucoup de configurations à plusieurs endroits contrairement à Microprofile, qui nécessite principalement des annotations. Cependant, le LRA coordinator (Narayana) de Microprofile demande plus de surveillance en production, car s’il tombe, la coordination n’est plus maintenue.

Sources

La démonstration des deux systèmes sur Github :

  • https://github.com/jefrajames/lra-demo
  • https://github.com/jefrajames/saga-demo

Documentation LRA :

  • Exemples sur quarkus https://quarkus.io/blog/using-lra/
  • Blog Narayana https://jbossts.blogspot.com/

Documentation Eventuate :

  • https://eventuate.io/
  • Livre Microservices Pattern de Chris Richardson

Conférence de Jean-François James à la Devoxx :

  • https://www.youtube.com/watch?v=7HC6ZfSy8M4

Direction Technique
Stéphane YVON
Proxiad NORD

  • Applicatif
  • Infrastructures
  • Cybersécurité
  • DevOps
  • Contact

PARIS

47 Rue de Ponthieu
75008 Paris
France
contact.idf@proxiad.com

LILLE

15 rue du Palais Rihour
59000 Lille
France
contact.nord@proxiad.com

ROUEN

4 Passage de la Luciline,
76000 Rouen
France
contact.normandie@proxiad.com

NANTES

275 Boulevard Marcel
Paul, 44800 Saint-
Herblain, France
contact.ouest@proxiad.com

STRASBOURG

3 Avenue de l'Europe,
67300 Schiltigheim
France
contact.est@proxiad.com

AIX-MARSEILLE

Europarc de Pichaury - 1330
av Guillibert de la Lauziére,
13290 Aix-en-Provence
contact.aixmarseille@proxiad.com

SOPHIA ANTIPOLIS

930 route des Dolines
06560 Valbonne
France
sophiantipolis@proxiad.com

LYON

170 Bd de Stalingrad
2e étage
69006 Lyon
contact.lyon@proxiad.com

BORDEAUX

Le Now Coworking,
Quai des Chartrons, Hangar 15
33300 Bordeaux
contact.bordeaux@proxiad.com

SOFIA

59 Boulevard G.M. Dimitrov,
1700 Sofia,
Bulgaria
contact.bulgaria@proxiad.com

PLOVDIV

6 Belgrad St,
4000 Plovdiv
Bulgaria
contact.bulgaria@proxiad.com

GREEN SI &
GREEN SI CONSULTING

47 rue de Ponthieu,
75008 Paris, France
contact.greensi@proxiad.com

SKOPJE

13 Maksim Gorki str, Nastel Business Center
1000 Skopje
Macédoine du Nord
contact.macedonia@proxiad.com

RENNES

801 Av. des Champs Blancs
35510 Cesson-Sévigné
contact.bretagne@proxiad.com

© 2025 PROXIAD

  • MENTIONS LéGALES
  • POLITIQUE DE CONFIDENTIALITé
  • siège social, 47 rue de ponthieu, 75008 paris, france
  • +33 1 44 83 83 70
Linkedin Instagram Youtube Facebook
Gérer le consentement aux cookies
Pour offrir les meilleures expériences, nous utilisons des technologies telles que les cookies pour stocker et/ou accéder aux informations des appareils. Le fait de consentir à ces technologies nous permettra de traiter des données telles que le comportement de navigation ou les ID uniques sur ce site. Le fait de ne pas consentir ou de retirer son consentement peut avoir un effet négatif sur certaines caractéristiques et fonctions.
Fonctionnel Toujours activé
Le stockage ou l’accès technique est strictement nécessaire dans la finalité d’intérêt légitime de permettre l’utilisation d’un service spécifique explicitement demandé par l’abonné ou l’utilisateur, ou dans le seul but d’effectuer la transmission d’une communication sur un réseau de communications électroniques.
Préférences
Le stockage ou l’accès technique est nécessaire dans la finalité d’intérêt légitime de stocker des préférences qui ne sont pas demandées par l’abonné ou l’utilisateur.
Statistiques
Le stockage ou l’accès technique qui est utilisé exclusivement à des fins statistiques. Le stockage ou l’accès technique qui est utilisé exclusivement dans des finalités statistiques anonymes. En l’absence d’une assignation à comparaître, d’une conformité volontaire de la part de votre fournisseur d’accès à internet ou d’enregistrements supplémentaires provenant d’une tierce partie, les informations stockées ou extraites à cette seule fin ne peuvent généralement pas être utilisées pour vous identifier.
Marketing
Le stockage ou l’accès technique est nécessaire pour créer des profils d’utilisateurs afin d’envoyer des publicités, ou pour suivre l’utilisateur sur un site web ou sur plusieurs sites web ayant des finalités marketing similaires.
Gérer les options Gérer les services Gérer les fournisseurs En savoir plus sur ces finalités
Voir les préférences
{title} {title} {title}
Logo Proxiad
  • Accueil
  • Expertises
  • Rejoignez-nous
  • Accueil
  • Expertises
  • Rejoignez-nous

NOUS REJOINDRE

CONTACTEZ-NOUS

SUIVEZ-NOUS

Linkedin Instagram Youtube Facebook
RAPPORT RSE