Architecture en microservices

Architecture en microservices

Le contexte

Vous développez une application d'entreprise côté serveur. Il doit prendre en charge une variété de clients différents, y compris les navigateurs de bureau, les navigateurs mobiles et les applications mobiles natives. L'application peut également exposer une API à des tiers. Il peut également s'intégrer à d'autres applications via des services Web ou un courtier de messages (Broker). L'application gère les requêtes (requêtes et messages HTTP) en exécutant la logique métier ; accéder à une base de données ; échanger des messages avec d'autres systèmes ; et renvoyer une réponse HTML/JSON/XML. Il existe des composants logiques correspondant à différents domaines fonctionnels de l'application.

Problème

Quelle est l'architecture de déploiement de l'application ?

Les forces

  • Il y a une équipe de développeurs travaillant sur l'application
  • Les nouveaux membres de l'équipe doivent rapidement devenir productifs
  • L'application doit être facile à comprendre et à modifier
  • Vous souhaitez pratiquer le déploiement continu de l'application
  • Vous devez exécuter plusieurs instances de l'application sur plusieurs machines afin de répondre aux exigences d'évolutivité et de disponibilité
  • Vous souhaitez tirer parti des technologies émergentes (frameworks, langages de programmation, etc.)

La solution

Définissez une architecture qui structure l'application comme un ensemble de services collaboratifs faiblement couplés. Cette approche correspond à l'axe Y du Scale Cube . Chaque prestation est :

  • Hautement maintenable et testable - permet un développement et un déploiement rapides et fréquents
  • Librement associé à d'autres services - permet à une équipe de travailler de manière indépendante la majorité du temps sur son ou ses services sans être affectée par les modifications apportées aux autres services et sans affecter les autres services
  • Déployable indépendamment - permet à une équipe de déployer son service sans avoir à se coordonner avec d'autres équipes
  • Capable d'être développé par une petite équipe - essentiel pour une productivité élevée en évitant le haut responsable de la communication des grandes équipes

Les services communiquent à l'aide de protocoles synchrones tels que HTTP/REST ou de protocoles asynchrones tels que AMQP. Les services peuvent être développés et déployés indépendamment les uns des autres. Chaque service possède sa propre base de données afin d'être découplé des autres services. La cohérence des données entre les services est maintenue à l'aide du modèle Saga


Exemples

Application de commerce électronique fictive

Imaginons que vous créez une application de commerce électronique qui prend les commandes des clients, vérifie l'inventaire et le crédit disponible, puis les expédie. L'application se compose de plusieurs composants, dont StoreFrontUI, qui implémente l'interface utilisateur, ainsi que certains services backend pour vérifier le crédit, maintenir l'inventaire et expédier les commandes. L'application est constituée d'un ensemble de services.


Contexte résultant

Avantages

Cette solution présente plusieurs avantages :

  • Permet la livraison et le déploiement continus d'applications volumineuses et complexes.
    • Maintenabilité améliorée - chaque service est relativement petit et est donc plus facile à comprendre et à modifier
    • Meilleure testabilité - les services sont plus petits et plus rapides à tester
    • Meilleure déployabilité - les services peuvent être déployés indépendamment
    • Il vous permet d'organiser l'effort de développement autour de plusieurs équipes autonomes. Chaque équipe (appelée deux pizzas) possède et est responsable d'un ou plusieurs services. Chaque équipe peut développer, tester, déployer et faire évoluer ses services indépendamment de toutes les autres équipes.
  • Chaque microservice est relativement petit :
    • Plus facile à comprendre pour un développeur
    • L'IDE est plus rapide, ce qui rend les développeurs plus productifs
    • L'application démarre plus rapidement, ce qui rend les développeurs plus productifs et accélère les déploiements
  • Amélioration de l'isolation des pannes. Par exemple, s'il y a une fuite de mémoire dans un service, seul ce service sera affecté. Les autres services continueront de traiter les demandes. En comparaison, un composant qui se comporte mal dans une architecture monolithique peut faire tomber l'ensemble du système.
  • Élimine tout engagement à long terme envers une pile technologique. Lors du développement d'un nouveau service, vous pouvez choisir une nouvelle pile technologique. De même, lorsque vous apportez des modifications majeures à un service existant, vous pouvez le réécrire à l'aide d'une nouvelle pile technologique.

Désavantages

Cette solution présente plusieurs inconvénients :

  • Les développeurs doivent faire face à la complexité supplémentaire de la création d'un système distribué :
    • Les développeurs doivent implémenter le mécanisme de communication inter-services et gérer les pannes partielles
    • La mise en œuvre de requêtes couvrant plusieurs services est plus difficile
    • Tester les interactions entre les services est plus difficile
    • La mise en œuvre de demandes couvrant plusieurs services nécessite une coordination minutieuse entre les équipes
    • Les outils de développement/IDE sont orientés vers la création d'applications monolithiques et ne fournissent pas de support explicite pour le développement d'applications distribuées.
  • Complexité du déploiement. En production, il y a aussi la complexité opérationnelle du déploiement et de la gestion d'un système composé de nombreux services différents.
  • Augmentation de la consommation de mémoire. L'architecture de microservice remplace N instances d'application monolithiques par NxM instances de services. Si chaque service s'exécute dans sa propre JVM (ou équivalent), ce qui est généralement nécessaire pour isoler les instances, il y a alors une surcharge de M fois plus d'exécutions JVM. De plus, si chaque service s'exécute sur sa propre VM (par exemple, une instance EC2), comme c'est le cas chez Netflix, la surcharge est encore plus élevée.

Problèmes

Il y a de nombreux problèmes que vous devez résoudre.

Quand utiliser l'architecture microservice ?

L'un des défis liés à l'utilisation de cette approche est de décider quand il est logique de l'utiliser. Lors du développement de la première version d'une application, vous n'avez souvent pas les problèmes que cette approche résout. De plus, l'utilisation d'une architecture distribuée élaborée ralentira le développement. Cela peut être un problème majeur pour les startups dont le plus grand défi est souvent de savoir comment faire évoluer rapidement le modèle commercial et l'application qui l'accompagne. L'utilisation de fractionnements sur l'axe Y peut rendre beaucoup plus difficile l'itération rapide. Plus tard, cependant, lorsque le défi est de savoir comment évoluer et que vous devez utiliser la décomposition fonctionnelle, les dépendances enchevêtrées peuvent rendre difficile la décomposition de votre application monolithique en un ensemble de services.

Comment décomposer l'application en services ?

Un autre défi consiste à décider comment partitionner le système en microservices. C'est tout un art, mais il existe un certain nombre de stratégies qui peuvent aider :

  • Décomposer par capacité métier et définir les services correspondant aux capacités métier.
  • Décomposer par sous-domaine de conception axée sur le domaine .
  • Décomposez par verbe ou cas d'utilisation et définissez les services qui sont responsables d'actions particulières. par exemple, un Shipping Servicequi est responsable de l'expédition des commandes complètes.
  • Décomposer par noms ou ressources en définissant un service responsable de toutes les opérations sur les entités/ressources d'un type donné. par exemple un Account Serviceresponsable de la gestion des comptes d'utilisateurs.

Idéalement, chaque service ne devrait avoir qu'un petit ensemble de responsabilités. (Oncle) Bob Martin parle de la conception de classes en utilisant le principe de responsabilité unique (SRP) . Le SRP définit une responsabilité d'une classe comme une raison de changer et stipule qu'une classe ne devrait avoir qu'une seule raison de changer. Il est logique d'appliquer également le SRP à la conception de services.

Une autre analogie qui aide à la conception de services est la conception des utilitaires Unix. Unix fournit un grand nombre d'utilitaires tels que grep, cat et find. Chaque utilitaire fait exactement une chose, souvent exceptionnellement bien, et est destiné à être combiné avec d'autres utilitaires à l'aide d'un script shell pour effectuer des tâches complexes.

Comment maintenir la cohérence des données ?

Afin d'assurer un couplage souple, chaque service dispose de sa propre base de données. Maintenir la cohérence des données entre les services est un défi car les transactions en 2 phases validées/distribuées ne sont pas une option pour de nombreuses applications. Une application doit plutôt utiliser le modèle Saga . Un service publie un événement lorsque ses données changent. D'autres services consomment cet événement et mettent à jour leurs données. Il existe plusieurs façons de mettre à jour les données et de publier des événements de manière fiable, notamment Event Sourcing et Transaction Log Tailing .

Comment implémenter les requêtes ?

Un autre défi consiste à implémenter des requêtes qui doivent récupérer des données appartenant à plusieurs services.

  • Les modèles API Composition et Command Query Responsibility Segregation (CQRS) .

Il existe de nombreux modèles liés au modèle de microservices. L' architecture monolithique est une alternative à l'architecture microservice. Les autres modèles résolvent les problèmes que vous rencontrerez lors de l'application de l'architecture de microservice.

  • Modèles de décomposition
    • Décomposer par capacité métier
    • Décomposer par sous-domaine
  • Le modèle Base de données par service décrit comment chaque service a sa propre base de données afin d'assurer un couplage lâche.
  • Le modèle API Gateway définit la façon dont les clients accèdent aux services dans une architecture de microservice.
  • Les modèles de découverte côté client et de découverte côté serveur sont utilisés pour acheminer les demandes d'un client vers une instance de service disponible dans une architecture de microservice.
  • Les modèles de messagerie et d'appel de procédure distante sont deux manières différentes pour les services de communiquer.
  • Les modèles Service unique par hôte et Services multiples par hôte sont deux stratégies de déploiement différentes.
  • Modèles de préoccupations transversales : modèle de châssis de microservice et configuration externalisée
  • Modèles de test : test de composant de service et test de contrat d'intégration de service
  • Disjoncteur
  • Jeton d'accès
  • Modèles d'observabilité :
    • Agrégation de journaux
    • Métriques d'application
    • Journalisation des audits
    • Traçage distribué
    • Suivi des exceptions
    • API de vérification de l'état
    • Déploiements et modifications des journaux
  • Modèles d'interface utilisateur :
    • Composition de fragment de page côté serveur
    • Composition de l'interface utilisateur côté client

Utilisations connues

La plupart des sites Web à grande échelle, notamment Netflix , Amazon et eBay , sont passés d'une architecture monolithique à une architecture de microservices.

Netflix, qui est un service de streaming vidéo très populaire qui est responsable de jusqu'à 30 % du trafic Internet, possède une architecture orientée services à grande échelle. Ils traitent plus d'un milliard d'appels par jour vers leur API de streaming vidéo à partir de plus de 800 types d'appareils différents. Chaque appel d'API génère en moyenne six appels aux services backend.

Amazone.com avait à l'origine une architecture à deux niveaux. Afin d'évoluer, ils ont migré vers une architecture orientée services composée de centaines de services backend. Plusieurs applications font appel à ces services dont les applications qui implémentent Amazon.com et l'API de service Web. L'application de site Web appelle 100 à 150 services pour obtenir les données utilisées pour créer une page Web.

Le site d'enchères ebay.com est également passé d'une architecture monolithique à une architecture orientée services. Le niveau d'application se compose de plusieurs applications indépendantes. Chaque application implémente la logique métier pour un domaine de fonction spécifique tel que l'achat ou la vente. Chaque application utilise des fractionnements sur l'axe X et certaines applications telles que la recherche utilisent des fractionnements sur l'axe Z. Ebay.com applique également une combinaison de mise à l'échelle de style X, Y et Z au niveau de la base de données. ebay.com a également évolué d'une architecture monolithique vers une architecture orientée services. Le niveau d'application se compose de plusieurs applications indépendantes. Chaque application implémente la logique métier pour un domaine de fonction spécifique tel que l'achat ou la vente. Chaque application utilise des fractionnements sur l'axe X et certaines applications telles que la recherche utilisent des fractionnements sur l'axe Z. Ebay.com applique également une combinaison de mise à l'échelle de style X, Y et Z au niveau de la base de données.

Il existe de nombreux autres exemples d'entreprises utilisant l'architecture de microservices.


Traduit à partir de Source

Commentaires