Exemple de design de

microservices

Rappels sur les microservices

Le monolithe

  • Petit et rapide au début
  • Gros et lent avec le temps
  • Accumulation de dette technique
  • Maintenance de plus en plus coûteuse

coût

temps

Le microservice

  • Un monolithe qui ne grandit jamais
  • Dette technique raisonnable
  • Un coût de maintenance raisonnable

coût

temps

Architecture microservice

  • Des boîtes noires qui échangent des messages
  • Chaque service ignore ce que fait son voisin
    (il n'en connait que l'interface - API)

coût

temps

Risques

  • Externaliser la complexité (le plat de spaghetti) dans les relations entre services
    => formaliser les règles de communication
    • normes
    • formats
    • asynchrone, synchrone, offline
  • Augmenter le nombre de pannes possibles
    => formaliser les règles de conception
    • service minimum
    • résilience aux pannes
    • redéploiement automatique

Les contraintes et avantages

Les points clés d'un microservice

  • Élastique
  • Résilient
  • Composable
  • Minimal
  • Complet

Les points clés

Élastique

  • ​il peut y avoir une ou plusieurs instances
  • permet la montée en charge

Les points clés

Résilient

  • ​ne doit pas planter si un autre est indisponible
  • lors d'une interruption dû à une mise à jour
  • lorsque la base est momentanément indisponible

Les points clés

Composable

  • seule l'API définit le service
  • pas de couplage
  • éviter les services de conversion de format

Les points clés

Minimal

  • ​responsabilité unique
  • pas de fonctionnalité inutile

Les points clés

Complet

  • toutes les fonctionnalités nécessaires
  • il doit être autonome
  • possède sa propre base de données

Quelques analogies avec la POO

SOLID

  • Simple responsibility principle
  • Open/close principle
  • Liskov substitution principle
  • Interface segregation principle
  • Dependency inversion principle

Corollaires

Stateless

L'élasticité implique que toute requête doit être

  • stateless
  • self content

Autorisation

  • le système étant ouvert tout est accessible
    => utilisation d'un contrôle d'accès
  • pour ne pas dépendre d'un service tiers
    => via token self content
    => contrôle d'accès autonome

Droits d'accès

  • le service définit et gère
    • ses propres rôles
    • ses propres droits

Format d'échange

  • utilisation de normes pour le format des données
    • existantes
    • ou à créer
  • protocole RESTful pour le CRUD des ressources

Découverte du service

  • ce n'est pas wsdl
  • néanmoins des standards apparaissent
    • OpenAPI (swagger) permet de spécifier l'API

Typologie des services

  • Différentes types de services ayant chacun leur rôle
    • référentiels = réalise CRUD sur des entités
    • fonctions = réalise une fonction
    • intermédiateur = converti un format
    • orchestre/chorégraphe = appelle d'autres services
    • ...
  • si plusieurs rôles dans un même service 

Phylogénie des services

  • les services peuvent évoluer
  • se scinder si deux rôles
  • ou fusionner si couplage

Webhooks

  • ils sont pour les services
    ce que sont les messages pour les objets
  • évitent le couplage

Principaux types

Référentiel

Rôle

  • API CRUD sur des entités
  • Interface entre l'API et le stockage des entités
  • Gère les droits d'accès aux entités
  • Les limitations ne sont pas de son ressort

Exemples

  • Tiers
  • Tâches
  • ...

Fonction

Rôle

  • Réaliser une ou des fonctions
  • Gère les droits d'accès aux fonctions

Exemples

  • Envoyer un SMS
  • Fusionner des données dans un modèle de document
  • Effectuer un virement

Intermédiateur

Rôle

  • S'insérer entre deux services aux formats incompatibles
  • Convertir des données d'un format vers un autres

Exemples

  • conversion d'un format spécifique d'utilisateurs vers le format adullact
  • ...

Orchestrateur

Rôles

  • Composer une fonction complexe en appelant les autres services
  • Réaliser la chorégraphie entre les services

Exemples

  • Des fonctions métier
  • ...

Choses communes

Choses communes

La plupart des services ont en commun

  • l'exposition des informations et status
  • le contrôle d'accès
  • les webhooks
  • le multi-tenant & configurations
  • la gestion des ressources

Informations

& Status

Informations

  • liens de découverte du service
  • rôles
  • version
  • swagger
  • license

Status

  • état du service
  • états des dépendances

Contrôle d'accès

Distinguer les rôles

Rôles Groupes

Groupe

Le groupe dont on fait parti, c'est lié à :

  • l'organigramme
  • la hiérarchie
  • les unités
  • ...

exemples :

  • marketing, stagiaires, permanents, développeur, rh,...

Un utilisateur peut faire parti de plusieurs groupes

Rôle

Le rôle que l'on a vis-à-vis du service, dépend de ce qu'on a le droit de faire :

  • administrateur : gère l'ensemble du service
  • manager : gère un tenant du service
  • utilisateur : utilise le service

Les rôles peuvent être déclinés en sous-rôles pour plus de finesse

  • rédacteur, contrôleur,...

Exemple

On a

  • un utilisateur chez un intégrateur de service
  • il a accès à trois plateformes/tenants
    • test/* : celle de test pour vendre
    • prod/client : celle de son client qu'il est en train d'intégrer
    • prod/lui-même : celle qu'il utilise pour gérer ses projets
  • ses accès sont respectivement :
    • administrateur : il doit pouvoir faire ce qu'il veut
    • manager : il doit pouvoir modifier le tenant de son client
    • utilisateur : il est simple utilisateur de son propre tenant

​Pourtant c'est le même utilisateur faisant parti des mêmes groupes

Group/Role mapping

  • Pour connaître les droits d'un utilisateur il faut déterminer ces rôles à partir de ses groupes
  • C'est le rôle du dictionnaire groupe/rôle qui à chaque groupe associée des rôles
  • Ce dictionnaire est spécifique à chaque tenant

tenant

group/role

groups

roles

requête

utilisateur

Le problème de l'initalisation

  • global/pas de tenant => il faut qu'un administrateur initialise le groupRoleMapping général pour l'administrateur => 💀
    => il faut un compte initial dans la config
    supprimé par la suite
     
  • un tenant est créé => le groupRoleMapping de ce tenant est vide => le manager n'a pas accès et ne peut pas mettre le mapping à jour => 💀
    => l'administrateur doit ajouter un groupe pour le manager, ensuite le manager peut gérer le mapping de son tenant

 

Attention aux droits

💀

le manager ne doit pas pouvoir ajouter le rôle administrateur dans le mapping de son tenant

sinon il peut augmenter ses propres droits

Basic auth

username + password

  • ne contient pas d'authentification intrinsèque
    => il faut authentifier l'utilisateur avec son identifiant et son mot de passe
  • ne contient pas de payload
    => il faut recherche les groupes associés à l'utilisateur

=> gérer une liste interne contenant les utilisateurs autorisés et définir pour chaque utilisateur la liste des groupes dont il fait parti (ou faire appel à un service tiers)

 

Utile pour

  • les tests
  • l'initialisation (temporairement)

JWT

Token self content avec authentification & payload

  • on sait que l'utilisateur a été authentifié par l'émetteur du token
  •  self content peut donc contenir toute l'information nécessaire
    • groupes par tenant
    • id de l'utilisateur

Droits positif/négatif

  • droit positif 
    tout le monde a le droit sauf ...
  • droit négatif
    personne n'a le droit sauf ...

Toujours utiliser un droit de même type

Ne jamais mixer les deux types sur une même ressource

Webhooks

Webhooks

  • ce sont les messages du service 
  • permettent chaîner les services
  • pas de norme, mais des standards apparaissent

Webhook

définit par

  • un déclencheur
    • une opération
      • création, mise à jour, suppression
    • ​​​une cible
      • une ressource ou un ​type de ressources
  • une réponse : l'appel d'un service
    • ​opération : GET, POST,...
    • une url
    • un corps
      • ​brut, filtré, reformaté,...

Création d'un webhook

un webhook est défini

  • au niveau du service ou du tenant
  • statiquement ou dynamiquement
    • dans la configuration
    • par un appel à une API
  • avec ou sans durée de vie

Exemple

référentiel tâches

PATCH tâche

POST sms

data wharehouse

POST tâche

envoi de sms

Exemple

référentiel tâches

PATCH tâche

formatage sms

POST tâche

data wharehouse

POST tâche

envoi de sms

POST sms

Exemple de configuration

module tiers MGDIS

"webhooks": [
  {
    "topic": "POST+*/tiers",
    "callback": "/document-collect/stnazaire/root/tiers?cmisaction=createFolder&propertyId[0]=cmis:name&propertyValue[0]={reference}&propertyId[1]=cmis:objectTypeId&propertyValue[1]=cmis:folder&succinct=true",
    "method": "POST",
    "options": {
      "withoutBody": true
    }
  },
  {
    "topic": "POST+*/tiers",
    "callback": "/request/api/stnazaire/collections/tiers/{reference}",
    "method": "PUT",
    "headers": {
      "Authorization": "Basic YWRtaW46QzdOYVdWMzlwM1M4R0hFd2RTTjNIZ1lwVzFXMGVtS1E="
    }
  },
  {
    "topic": "POST+*/tiers",
    "callback": "https://wwx2.mairie-saintnazaire.fr/BlueAccess/application/referentiel_association_TEST/modules/webhook/index.php?reftiers={reference}",
    "method": "PUT"
  },
]

Multi-tenant & Configuration

Multi-tenant

  • partager un même service entre plusieurs locataires
  • tenant client
    (même si 99% du temps c'est pareil)
  • le tenant est créé dynamiquement
    (à chaud pas de redéploiement)

Configuration

Plusieurs parties :

  • paramètres globaux du service accessibles à l'administrateur
  • associés à chaque tenant
    • paramètres accessibles à l'administrateur (privés)
    • paramètres accessibles au manager (publics)

Ressources/objets

Les schémas

Ils sont obligatoires pour :

  • la validation de l'API
    • définition (OpenAPI/swagger)
    • requête
    • réponse
  • la gestion du format de la persistance

Persistance

Rappel

  • L'objet manipulé par
    • l'ihm (reçu par le navigateur via l'API)
    • le serveur (pour préparer sa réponse)
    • la base de données (pour les stocker)

NE SONT PAS (forcément/souvent) LES MÊMES

Snapshot

On ne garde que le dernier état de la ressource

  • simple
  • la ressource est immédiatement disponible
  • permet peu de choses

Incrémentale

On stocke toutes les modifications réalisées sur la ressource

  • complet : qui, quoi, quand
  • besoin de reconstituer la ressource
  • permet de retracer l'historique

(on peut ajouter un cache snapshot pour accélérer l'accès)

Référentiel

Un référentiel doit  gérer l'historique des ressources qu'il gère

=>

Utilisation de la sauvegarde incrémentale obligatoire

Fonctions & orchestre

Fonctions

  • Simples (pas d'état)
    • intermédiateurs
  • Complexes (avec état)
    • fonctionnalités métier
    • orchestration

Simples

Intermédiateurs

  • pas de stockage d'information
    • fonction pure
    • idempotence
  • donc service simplifié
    • facilement remplaçable
    • authentification simplifiée (voir inutile)
    • utilisation d'EIP => Apache Camel
    • container obligatoire

Complexes

Métier ou orchestrateur

  • éventuellement du stockage d'information
    • pas fonction pure
    • pas d'idempotence
  • donc service plus classique
    • authentification complète
      (mais rôles souvent moins nombreux)
    • pour les orchestrateur => EIP / BPM
      (Apache Camel / Bonita)
    • pour les autres => comme un service référentiel

Apache Camel

Basé sur les Entreprise Integration Pattern
(C'est à l'intégration ce que sont les Design Patterns à la POO)

Migration

Du monolithe

aux services

en trois étapes

  • factoriser/modulariser
  • créer des api
  • faire des services 

Découpage

première étape

  • factoriser/modulariser le code existant
  • limiter les dépendances

API

deuxième étape

  • créer des api
  • faire des tests unitaires dessus
  • utiliser les API

Tests

Migration

troisième étape

  • faire des services 
  • extraire le code 

Tests

D'une base à une autre

  • dissocier les bases de données en trois étapes
  • la troisième vous étonnera

Dissocier lecture et écriture

première étape

  • utiliser l'api pour l'écriture

Dissocier les données

deuxième étape

  • récrire le service
  • utiliser une autre base

Migration totale

troisième étape

  • utiliser uniquement l'API

Environnement

Déploiement

Containers rules the world

  • pour les containers
    • Docker s'impose 
  • pour la composition de containers
    • Docker Compose
  • pour le cluster
    • Docker Swarm ↘
    • Kubernetes (k8s) ↗

Atelier logiciel

  • Automatiser du développement au déploiement
  • Utiliser les outils nécessaires
    • organisation : redmine, jira, trello,...
    • automatisation : jenkins
      • qualité : sonarqube, linters,...
      • tests unitaires
      • tests d'intégration
    • bug tracker : mantis, redmine, jira,...

Log

Monitorer

  • Sans log impossible de suivre le fonctionnement, l'état de santé des nombreux containers
  • Outiller les logs : ELK (ElasticSearch Logstash Kibana)

Prendre la solution adaptée

Exemples de design de microservices

By Benoît Chanclou

Exemples de design de microservices

en cours

  • 312