samedi 16 mai 2020

Introduction aux Microservices: partie 1

L’émergence des architectures microservices est la réponse de l’industrie aux problèmes rencontrés avec les monolithes et avec les implémentations de SOA avec L’ESB. Le terme “microservice” est apparu dans le vocabulaire du monde des applications d’entreprise il y a déjà quelques années, mais on l’entend de plus en plus ces derniers temps. Ce modèle d’architecture logicielle devient toujours plus attrayant et nombreux sont les nouveaux projets qui l’adoptent. Les résultats sont jusqu'à présent positifs à tel point que ce style est en train de devenir le choix par défaut pour la création des logiciels d'entreprise. Cependant, il n’existe pas beaucoup d'informations qui décrivent ce modèle d’architecture, et comment le mettre en œuvre, en particulier pour le public francophone.


Dans cet article, je présente les concepts fondamentaux des microservices: la théorie derrière les microservices, la définition des concepts, les caractéristiques et la structure d'un microservice.


La théorie derrière les microservices

Dans le monde logiciel, la mise à l’échelle (ou la scalabilité) est l'un des principaux moteurs de tout type de solution architecturale. Dans leur livre à succès intitulé « The Art of Scalability » qui peut être traduit en français par « L’art de la mise à l’échelle », les auteurs Martin Abbott et Michael Fisher définissent le modèle du cube de l’échelle, « The scale cube » en anglais, qui décrit trois dimensions de la mise à l'échelle d’une solution applicative comme on peut voir sur cette image.

Théorie derrière les microservices
Le cube de l'échelle
 

L'axe X représente la mise à l'échelle horizontale. Elle se fait par clonage de l'application, accompagnée parfois d’une réplication d’un jeu de données. On a vu dans le premier article que cela se fait bien avec les monolithes, notamment en exécutant plusieurs instances de l’application derrière un équilibreur de charge.


L'axe Z représente la mise à l'échelle de l'application en divisant des choses similaires. L'idée de l'axe Z peut être mieux comprise en utilisant le concept de partitionnement, où les données sont partitionnées et l'application redirige les requêtes vers les partitions correspondantes en fonction des valeurs entrées par l’utilisateur, comme cela est généralement fait avec la partition des tables dans les bases de données.


La mise à l’échelle suivant l’axe Y est celle qui nous intéresse dans cet article. Elle correspond à la décomposition fonctionnelle d’un monolithe. Elle se concentre sur la séparation des services et des données suivant des frontières fonctionnelles. Les fractions de la division sont « différentes » les unes des autres. Les exemples dans les solutions de commerce électronique peuvent être la séparation de la fonction de recherche et de la fonction de navigation, de la fonction de vérification et de celle de l'ajout au panier, de la fonction de connexion et de celle de la gestion du statut du compte, etc.
Chaque service met en œuvre un ensemble de fonctionnalités connexes. De plus, chaque service doit avoir ses propres données non partagées pour garantir une haute disponibilité et une isolation des pannes. La mise à l'échelle de l'axe Y partage l'avantage d'augmenter la mise à l’échelle des transactions avec tous les axes du cube. Elle permet aussi de mettre à l’échelle chaque service indépendamment, suivant les 2 autres axes que sont X et Z, et d’allouer plus de ressources seulement aux services qui en ont besoin.


Définition

Les microservices désignent une approche architecturale du développement d'applications. On trouve dans la littérature plusieurs définitions de l'architecture microservices selon les auteurs. J’ai retenu pour cet article la définition de Martin Fowler et James Lewis [1]. Le style architectural des microservices est une approche pour construire une application logicielle en assemblant plusieurs petits services qui s'exécutent chacun dans son propre processus et qui communiquent entre eux par des mécanismes légers, le plus souvent des API de ressource HTTP. Ces services sont bâtis autour des capacités d’affaires de l’entreprise, et sont déployés de façon indépendante par des mécanismes automatisés. Il y a un strict minimum de gestion centralisée de l’ensemble, et chacun d’eux peut être développé en utilisant un langage de programmation différent, ainsi des technologies de stockage de données différentes.
Dans cet article et ceux qui vont suivre, j’utiliserai indifféremment les expressions “architecture des microservices” et “architecture microservice” pour désigner la même chose.



Exemple d'une architecture de microservices
Exemple d'une architecture de microservices


Cet exemple présente une décomposition possible en microservices pour une application de commerce électronique. On a une architecture avec 4 microservices : 
  • Le premier microservice est celui de la gestion des comptes clients. Il a sa propre base des données et expose une interface REST API. 
  • Le second est le service de gestion des inventaires. Il a aussi sa propre base des données et expose également une interface REST API. 
  • Le troisième est le service de gestion des livraisons qui est aussi connecté à sa propre base des données, et expose comme les deux services précédents une interface REST API. 
  • Le 4e est un microservice un peu particulier, qui expose une interface Web aux utilisateurs pour accéder depuis leur navigateur aux opérations des 3 autres microservices

Les caractéristiques d'un microservice

Notons pour commencer qu’un microservice est d’abord un service, et que d'un point de vue général, un service est un logiciel qui met ses fonctionnalités à disposition via une API publiée faisant partie d'un contrat de service. Plusieurs caractéristiques définies pour les services SOA s'appliquent aussi aux microservices.

Voici quelques caractéristiques des services qui s'appliquent également aux microservices.

1. Contrat de service


Comme un service dans SOA, un microservice est décrit par le biais d’un contrat de service bien défini. C’est dans le contrat qu’on indique quelles sont les fonctionnalités qui sont disponibles pour une invocation publique. Un des principes fondamentaux des architectures à base de services veut que des services faisant partie du même inventaire soient conformes aux mêmes normes de conception de contrat, afin de garantir une interopérabilité intrinsèque. Il existe de nombreuses techniques utilisées pour définir les contrats de service. Le schéma JSON, WADL, Swagger et RAML en sont quelques exemples.

2. Couplage lâche


Les microservices sont indépendants et faiblement couplés. Le couplage fait référence à une mesure de dépendance entre deux composants d’un système. Lors de la conception des microservices, les architectes mettent constamment l’accent sur la réduction (le «relâchement») des dépendances entre le contrat de service et sa mise en œuvre d’une part, et entre le service et ses potentiels consommateurs d’autre part. Dans la plupart des cas, les microservices acceptent un événement en entrée et répondent avec un autre événement. En général, les microservices communiquent soit par HTTP en utilisant les principes REST, soit par messagerie sur un bus léger. Une communication basée sur les messages offre des niveaux de découplage plus élevés.

3. Abstraction de service

Les contrats de service contiennent le minimum d’informations dont un client a besoin pour invoquer une opération du service. Les informations disponibles sur les services sont limitées à celles qui sont publiées dans les contrats de service. Le consommateur du service ne doit pas être au courant des détails de la logique des traitements effectués par les opérations du service.

4. Les microservices sont réutilisables


Les microservices contiennent et expriment une logique agnostique et peuvent être positionnés comme des ressources d'entreprise réutilisables. Chaque fois qu’on crée un service, on recherche les moyens de rendre ses capacités sous-jacentes utiles à plus d'un but.

5. Les microservices sont sans état

Les microservices bien conçus sont sans états. Ils minimisent la consommation de ressources en déléguant la gestion des informations d'état lorsque c’est nécessaire. Une gestion excessive des informations d'état peut compromettre la disponibilité d'un service ainsi que la possibilité de prévoir son comportement. Dans le cas où il est nécessaire de maintenir un état, il est conservé dans une base de données.

6. Les microservices sont détectables

Dans un environnement typique de microservices, ces derniers annoncent eux-mêmes leur existence et se rendent disponibles pour la découverte. Les microservices sont livrés avec des métadonnées de communication grâce auxquelles ils peuvent être efficacement découverts et interprétés.

7. Les microservices sont autonomes


Les microservices exercent un haut niveau de contrôle sur leur environnement d'exécution sous-jacent. Il faut pour cela implémenter un environnement d'exécution indépendant et une frontière fonctionnelle bien délimitée.

8. Les microservices sont composables


Les microservices sont des participants efficaces à la composition, quelles que soient la taille et la complexité de cette composition. La capacité de pouvoir composer efficacement des services est une condition essentielle à l’atteinte d’un des objectifs fondamentaux des architectures des microservices. La composabilité des services est obtenue soit par l'orchestration des services, soit par la chorégraphie des services.

Structure d'un microservice

Le diagramme suivant montre la structure d'un microservice avec une architecture dite hexagonale. Le cœur du service est sa logique d’affaire et se trouve au centre de l'hexagone. Elle est entourée d'adaptateurs qui communiquent avec d'autres services et applications.

Structure d'un microservice
Structure hexagonale d'un microservice


Examinons chaque partie de cette structure.

Un service a une API

Du point de vue de ses consommateurs, la seule chose qui compte dans un service est son API. Une API de service se compose d'opérations et d'événements publiés.

Les opérations

Il existe deux types d'opérations: les commandes et les requêtes. Une commande est une opération qui modifie les données. Une requête est une commande qui interroge les données. Dans l’exemple de l’application du commerce électronique, le service de gestion des comptes clients implémente des commandes, telles que « créer un client » et « modifier un compte »; et aussi des requêtes telles que « chercher un client » ou « lister tous les clients ».
Les opérations d'un service sont appelées à l'aide d'une combinaison de protocoles synchrones, tels que REST ou gRPC, et la messagerie asynchrone. Les protocoles synchrones, en particulier REST, sont particulièrement utiles lors de l'implémentation d'API pour des clients externes comme les applications mobiles ou les applications Web à page unique (SPA). Cependant, les protocoles asynchrones sont généralement nécessaires lors de l'implémentation des commandes de gestion des transactions qui implique plusieurs services.

Les événements

Un service publie souvent des événements sur un canal de messagerie implémenté par un courtier de messages.

Logique d’affaires

C'est le cœur du service et la raison de son existence. Elle implémente les opérations de l'API et publie des événements. La logique d’affaires invoque les opérations d'autres services et s'abonne à leurs événements. Elle conserve les données dans la base de données du service.

Un service peut collaborer avec d'autres services

Lorsque les services collaborent, c'est via des APIs plutôt que via la base de données. Un service peut appeler les opérations d'un autre service. Un service peut également s'abonner aux événements publiés par un autre service. Le service de livraison, par exemple, s'abonne aux événements publiés par le service de gestion des comptes clients. Ainsi, lorsqu’un client change d’adresse, le service des comptes émet un évènement. Le service de livraison qui est abonné à cet évènement met à jour l’adresse du client dans sa base, c’est le pattern Saga.

La base de données d'un service est privée

Un service possède généralement une base de données qui stocke ses données et parfois des données répliquées à partir d'autres services. Afin d'assurer un couplage lâche, il est généralement mauvais pour les services de partager des tables de base de données. Au lieu de cela, les services doivent uniquement communiquer via leurs API.

Conclusion 


Que l'architecture microservice soit ou non le style privilégié par les développeurs à l'avenir, il s'agit clairement d'une idée puissante qui offre de sérieux avantages pour la conception et la mise en œuvre des applications d'entreprise.

Pour démarrer avec les microservices, je vous recommande ce cours sur Udemy: Les bases des architectures de microservices


Références:
[3]: https://developers.redhat.com/blog/2017/05/04/the-truth-about-microservices/





Aucun commentaire:

Enregistrer un commentaire