Un SI, ça doit évoluer en permanence, et si possible, pas en faisant une refonte totale tous les 3 ans. Alors je vous propose de parler de microservices, de Domain-driven design, de déclaratif, de réactif, de chorégraphie et de plein d'autres beaux concepts d'urbanisation qui servent justement à ça : rendre votre SI évolutif, pour que votre prochaine urbanisation dure au moins 10 ans.
1. Urbaniser un SI
pour 10 ans
BreizhCamp 2022 Christophe QUINTARD
Architecte @ Ouest
-France
2. L'urbanisation
L'art de relier les différents composants d'un SI.
On recherche la fiabilité, la rapidité, la sécurité…
… mais on n'oublie pas l'ÉVOLUTIVITÉ !
Christophe Quintard
3. Conventions
Une flèche droite pleine indique un APPEL D'API
Une flèche courbe pointillée indique un MESSAGE
GET
A B
A
B
Christophe Quintard
5. Archi point
-à-point
Toutes les briques reliées les
unes aux autres.
Difficile à faire évoluer, difficile
de maîtriser les données.
B
D E
C
A
Christophe Quintard
6. Archi monolithe
Un seul livrable, c'est simple à
maintenir...
...mais il ne faut pas intégrer
de briques tierces, sinon on
retombe dans le point
-à-point.
D E
Monolithe
Christophe Quintard
7. Archi base centrale
Plusieurs livrables, une base de
données centrale qui sert de
point d'échange.
Beaucoup de jointures en base,
donc beaucoup de dépendances.
=> Monolithe de base de
données :-(
base
monolithique
A C
B
Christophe Quintard
8. Archi bus de données
Toutes les briques reliées les
unes aux autres via un bus
de données.
Plus facile à faire évoluer,
relative maîtrise des données...
mais souvent il y a beaucoup
trop de métier dans le bus.
B
D E
C
A
Christophe Quintard
9. Archi tempête d'événements
Toutes les briques sont
connectées point
-à-point,
mais à travers des files de
messages.
( Bon courage pour la
supervision ! )
A B C
D E F
Christophe Quintard
11. Découplage
On intercale un PROXY (ou l'équivalent) devant une brique pour
pouvoir la faire ÉVOLUER ou la REMPLACER sans impact sur le
reste du SI.
A
B
Proxy
C
A
B
Christophe Quintard
12. Source de vérité
Une donnée n'est pas exposée par son producteur, mais mise à
disposition dans une SOURCE DE VÉRITÉ. On peut recopier la
donnée, mais on doit rester en phase avec la source.
Copie
partielle
Source de
vérité
Agrégation avec
une autre donnée
Consommateur
GET
GET
GET
Producteur
PUT
Christophe Quintard
13. Source de vérité
L'utilisation d'une SOURCE DE VÉRITÉ permet d'avoir PLUSIEURS
PRODUCTEURS pour une même donnée. Les producteurs qui ont
une copie des données doivent aussi être CONSOMMATEURS.
Copie
partielle
Source de
vérité
Agrégation avec
une autre donnée
Producteur
pur
PUT GET
GET
Producteur
(avec copie des données)
GET/PUT
Christophe Quintard
14. Réactif
Plutôt que de POLLER une API, on ÉCOUTE les messages qu'elle
émet à chaque changement. L'émetteur ne connaît pas le
récepteur (c'est aussi du découplage)
B
A
B
A
Christophe Quintard
15. Microservices
Découper un Monolithe en Microservices
Pas de "Fwo Fizza Feam
" !
Ne vous demandez pas COMMENT découper mais POURQUOI ?
Livraisons couplées => Monolithe de livraison :-(
A B C A B
A C
Christophe Quintard
16. Domain-Driven Design
En Domain-Driven Design : le DOMAINE l'emporte sur l'OBJET !
Client
id
nom
adresse
mail
MarketingClient
id
pointsFidelite
segmentation
LivraisonClient
id
adresse
horaire
commentaire
Domaine Livraison
Domaine Marketing Domaine Groupe
Christophe Quintard
17. Déclaratif
En impératif, j'enchaîne les
ordres pour arriver à un état.
En déclaratif, j'indique un ÉTAT
À ATTEINDRE et un agent fait
le traitement en ASYNCHRONE.
On DÉCOUPLE, mais surtout on
DÉLÈGUE la COMPLEXITÉ.
PUT/GET
App
Agent
GET/PUT
Brique
App
Brique
API
Christophe Quintard
18. Chorégraphie
Plutôt que d'orchestrer, ce qui introduit du couplage,
préférez CHORÉGRAPHIER.
Brique 1 Brique 2
Chef
Brique 1 Brique 2
1) 2)
Christophe Quintard
19. Et pour mettre tout ceci en
pratique ?
Christophe Quintard
20. Standardiser - Industrialiser
Il est impossible de gérer plein de services tous uniques !
STANDARDISER les services, leur conf, leur API vous permettra
d'INDUSTRIALISER.
A C
B
B
A C
Outil de gestion Outil de gestion
?
?
?
Christophe Quintard
21. Référentiels
Un référentiel est une SOURCE DE VÉRITÉ avec un NOM et un
SCHÉMA. Il émet un message à chaque création, modification
et suppression. Il est le seul à stocker, et ne fait que cela.
PUT
Producteur /
Consommateur
Consommateur
Réf
Producteur /
Consommateur PUT
Consommateur
GET
Christophe Quintard
22. Référentiels
Le référentiel est LA brique essentielle pour URBANISER un SI !
PUT
Producteur /
Consommateur
Consommateur
Réf
Producteur /
Consommateur PUT
Consommateur
GET
Christophe Quintard
23. Vues
Besoin de faire des recherches croisées ?
Jointures en base => Monolithe de BDD :-(
Implémentez une VUE MATÉRIALISÉE !
(Une vue a une BDD et une file de
messages, tout comme un référentiel)
Vue
Réf Réf
App
Christophe Quintard
24. Métiers
Besoin de partager du code ?
Ne faites pas une librairie.
Faites un SERVICE MÉTIER.
- utilisable dans n'importe quel langage
- corrections prises en compte sans relivraison !
Métier
App
Christophe Quintard
25. Agents
Agents périodiques plutôt que des CRONs (pas de configuration
externe).
Agents réactifs pour de la chorégraphie.
Agent Agent
Christophe Quintard
27. Mettre en place un Backend
On rassemble tous ces
microservices en un BACKEND
.
Les données sont toujours
échangées par le backend.
Le backend du SI n'est pas le
backend des applications !
Backend
(réfs + vues + métiers + agents)
App
PUT
App
App
GET
Christophe Quintard
28. Ajouter des référentiels
On définit un référentiel pour chaque donnée échangée, et on
reroute les échanges.
Réf
App App
PUT
App App
PUT
Christophe Quintard
29. Ajouter des agents
Si une brique attend qu'on lui pousse les données, on met un
agent.
Réf
App App
PUT
App App
PUT
Agent
PUT
Christophe Quintard
30. Remplacer les API legacy
On implémente des nouveaux services, on réimplémente les
anciennes APIs comme proxy des nouveaux services.
Réf
GET / PUT
App
API
(implém.)
GET / PUT / POST
Métier
POST
App
API
(proxy)
GET / PUT / POST
Christophe Quintard
31. Découpler les briques techniques
Mettre un référentiel et un agent devant les briques techniques
pour : gérer le retry, absorber les pics de charge, différer
certaines demandes, avoir les statistiques d'usage, ...
PUT / GET
App Brique
Réf Agent
POST
PUT
App Brique
POST
Christophe Quintard
32. Chorégraphier au lieu d'orchestrer
On remplace les orchestrations par de la chorégraphie autour
des référentiels.
Réf
Orchestrateur
Service Service
Service
Service Service
Service Réf
Christophe Quintard
33. Enchaîner des traitements
L'élément dans le référentiel a un ÉTAT. Chaque agent réagit à
un état et fait passer à l'état suivant. Pas de KAFKA HELL !
PUT etat=valide
Agent
validation
Agent
traitement
Réf
etat==valide
etat==nouveau PUT etat=traite
Producteur
PUT etat=nouveau
Consommateur
etat==traite
Christophe Quintard
34. Chorégraphier avec du DDD
Réf
Stock
Agent
Site
Réf
Commande
Client
Agent
Réf
Commande
Fournisseur
Agent
Réf
Marketing
Client
Agent
Réf
Avantage
Client
Réf
Commande
Fournisseur
mise à jour des stocks réapprovisionnement auto
mise à jour compte fidélité calcul des avantages
Agent
Réf
Livraison
création de la livraison
Agent TMS
calcul de tournée
prise de commande
Christophe Quintard
36. Conception des APIs
Normez le nom de vos services : ref-commercial-client
-v1, vue-
client
-v2, agent
-stock-reassort
-v1, …
Standardisez vos APIS :
GET /ref-commercial-client
-v1/elements?q=...
GET /ref-commercial-client
-v1/element/ID
PUT /ref-commercial-client
-v1/element/ID
DELETE /ref-commercial-client
-v1/element/ID
Vous pourrez ainsi implémenter un client générique.
Christophe Quintard
37. La création en HTTP/REST
Ne créez pas avec POST... Créez avec PUT !
id : 1234
a : 1
POST /element {a : 1}
id : 5678
a : 1
POST /element {a : 1}
doublon !
id : 1234
a : 1
PUT /element/1234 {a : 1}
id : 1234
a : 1
PUT /element/1234 {a : 1}
idempotent
Christophe Quintard
38. La modification en HTTP/REST
Ne modifiez avec PUT... Modifiez avec PATCH !
id : 1234
a : 1
PUT /element/1234 {a : 1}
id : 5678
a : 1
b : 1
id : 1234
a : 1
PATCH /element/1234 {a : 1}
id : 1234
a : 1
b : 1
id : 5678
a : 2
b : null
PUT /element/1234 {a : 2}
id : 1234
a : 2
b : 1
PATCH /element/1234 {a : 2}
(évolution de schéma) (évolution de schéma)
Christophe Quintard
39. La suppression en HTTP/REST
Supprimez avec DELETE, renvoyez toujours 200.
DELETE ne signifie pas " supprime cette ressource "
,
DELETE signifie " je veux que cette ressource soit supprimée "
.
Christophe Quintard
40. Pour un schéma évolutif
●
Id non significatif (pas de mail, de numéro de téléphone, de
numéro de sécu, de code produit, de code INSEE, ...)
●
Entier si seulement c'est nécessaire (somme, moyenne, ...)
●
Tableaux partout (changement de nom, de code, ...)
●
Pas de booléen (impossible d'ajouter un état)
Christophe Quintard
42. Gérer les services
Déclarer tous vos services dans
un référentiel pour déclencher :
- le déploiement,
- la mise à jour de la doc,
- le branchement à la
supervision,
- le branchement au datalake,
- l'envoi de messages,
- ...
Réf
services Agent
déploiement
Agent
màj doc
Agent
supervision
Agent
datalake
Christophe Quintard
43. Gérer les clés d'API
Déclarer toutes vos clés d'API
dans un référentiel.
Tous les services interrogent /
écoutent ce référentiel pour
avoir les clés d'API en mémoire
toujours à jour.
Réf
clés d'API
service
service
service
service
Christophe Quintard
44. Rapporter les erreurs
Associez un mail à chaque
service => rapportez les erreurs
5XX du service.
Associez un mail à chaque clé
d'API => rapportez les erreurs
4XX de la clé d'API.
Agent
rapport
Logs
GET
PUT
Réf envoi
de mail
Réf
services
Réf clés
d'API
GET
GET
Christophe Quintard