Tutoriel pour apprendre sous quelles conditions utiliser les microservices

Cherifa GHERSI AMARZOURGUI

Les microservices attirent de plus en plus l'attention des architectes. Il s'agit d'un pattern architectural semblable au SOA (architecture orientée services), la différence étant que les microservices ont tendance à valoriser des services plus restreints.
Dans ce tutoriel, nous allons découvrir ce qui se cache derrière ce terme.

Commentez

- Titre : Tutoriel pour apprendre sous quelles conditions utiliser les microservices

- Auteur : Cherifa GHERSI AMARZOURGUI

- Parution : 25 octobre 2017

- Licence : Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright ® 2017 Cherifa GHERSI AMARZOURGUI. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. Une évolution des SOA ?

- II-A. Microservices

- II-A-1. Les caractéristiques

- III. Avantages des microservices

- IV. Conditions d'utilisation

- IV-A. Déploiement

- IV-B. Hébergement peu coûteux

- IV-C. Erreurs à éviter

- IV-C-1. Découpage

- IV-C-2. Monitoring

- IV-C-3. Difficulté de la définition des microservices

- V. Du monolithique aux microservices

- VI. Les microservices pour une nouvelle application

- VII. Conclusion

I - Introduction

L'idée principale est de découper une application monolithique en morceaux composables. Ces morceaux devront travailler ensemble pour permettre l'ajout de nouvelles fonctionnalités plus rapidement et de faciliter la maintenance. Chaque composant est développé séparément, afin que l'application soit le produit de tous les microservices combinés.

Cette idée de séparer une application en plusieurs morceaux n'est pas nouvelle, il existe une autre architecture qui utilise le même concept : l'architecture orientée services « SOA », modèle d'interaction applicative mettant en œuvre plusieurs services. Il faut noter que les microservices comportent de nombreux avantages, mais aussi des points faibles non négligeables. En les utilisant là où il ne faut pas, nous risquons d'avoir plus d'inconvénients que d'avantages et de ne pas profiter de toute la puissance qu'ils offrent.

Nous allons commencer par définir l'architecture orientée services « SOA », base des architectures microservices.

II - Une évolution des SOA ?

L'architecture orientée services est une solution logicielle distribuée, se composant de trois acteurs principaux :

- le fournisseur de service : acteur responsable du développement du service, de son déploiement, de son exécution ;

- le consommateur de service : acteur utilisant les services en fonction de ses besoins ;

- le registre de services (service broker) : acteur qui enregistre les informations et permet de faire le lien entre consommateurs et fournisseurs. Les fournisseurs publient les services dans ces registres, qui sont ensuite consultés par les consommateurs.

On parle d'évolution puisque les microservices ont de nombreux points communs avec le SOA. Ils sont tous deux dédiés à la séparation des modules grâce à des services. Les microservices et le SOA ont cependant plusieurs différences, notamment au niveau de la définition des services, des méthodes, de leur création, mais aussi de leur étendue et de leurs principes. Il est intéressant de noter que parmi les entreprises qui utilisent actuellement les microservices, certaines, comme Netflix, considèrent qu'elles font du SOA. Les différences entre ces deux approches étant faibles, il est possible de dire que les microservices sont une manière particulière de faire du SOA.

II-A - Microservices

Un microservice est un service concentré sur une seule fonctionnalité, la plus simple possible ; l'interface exposée doit l'être également. Même s'il peut exister des interdépendances entre les différents microservices, chacun doit être déployé séparément.

II-A-1 - Les caractéristiques

- Concentré sur une seule fonctionnalité

Un microservice implémente et est responsable d'une seule fonctionnalité dans tout le système. Une fonctionnalité peut être une fonctionnalité métier contribuant à l'objectif du système, ou une fonctionnalité technique utilisée par plusieurs fonctionnalités métier.

- Déploiements individuels des microservices

Chaque microservice doit être déployable indépendamment des autres. Ce point est important : si l'on veut changer un microservice en particulier ou le mettre à jour, il faut être capable de le faire sans toucher aux autres microservices ni affecter leur exécution.

Le système doit continuer à fonctionner correctement durant la mise à jour du microservice en question, ainsi qu'après l'avoir redéployé.

- Constitution d'un ou plusieurs processus

Un microservice peut correspondre à un ou plusieurs processus. Il doit obligatoirement être hébergé sur des processus indépendants. En d'autres termes, il ne doit pas partager un processus avec un autre microservice.

Il peut être en revanche constitué de plusieurs processus, notamment dans le cas d'un accès à une base de données. Autrement dit, seul ce service peut accéder à cette base de données. C'est une façon d'éviter au maximum les interdépendances entre les microservices.

Par exemple si l'on développe deux microservices sur le même processus, nous risquons d'avoir des interdépendances qui vont conduire à l'obligation de déployer les deux en même temps, ce qui est contraire aux caractéristiques des microservices.

- Un microservice, une base de données

Un microservice ne peut pas utiliser la base de données d'un autre. Il doit avoir sa propre base de données où sont enregistrées les données dont il a besoin pour qu'il soit complètement indépendant des autres.

Par exemple, si le microservice B veut utiliser une donnée enregistrée dans la base de données A, il lui faudrait passer par l'API du microservice A et ne peut dans aucun cas passer directement à la base de données A.

- La taille des microservices

Comme l'indique le nom « micro », les microservices doivent être concentrés sur une seule et unique fonctionnalité, de façon à ce que leur développement et leur maintenance puissent se faire par des équipes de petite taille.

- Remplaçable

On doit pouvoir remplacer n'importe quel microservice du système dans un temps raisonnablement court.

III - Avantages des microservices

Utiliser les microservices amène des avantages divers provenant principalement de l'indépendance des équipes développant les services ainsi que de leur taille. Ils peuvent donc limiter les problèmes les plus fréquents rencontrés par de grandes applications tout en permettant une grande souplesse dans le développement et le déploiement.

- Hétérogénéité technologique

Un microservice n'a pas besoin de connaître la technologie utilisée par les autres microservices, il est donc tout à fait possible d'avoir des services n'utilisant pas les mêmes technologies. Cela permet d'utiliser une technologie plus adaptée pour un problème donné si nécessaire, mais aussi d'utiliser plus facilement de nouvelles technologies. Cependant, multiplier le nombre de technologies peut avoir des effets négatifs sur la mobilité des développeurs entre les services. Il vaut donc mieux limiter cette option aux cas où cela est nécessaire.

- Réutilisabilité

Dans le cas d'un service ne faisant que rendre disponible une API web, il est facile pour un autre service de le consommer, et ce quels que soient le langage, la plateforme, ou le système d'exploitation utilisé. On peut également utiliser ces services dans différentes applications si nécessaire. De plus, il devient plus facile de faire différentes interfaces pour le web et le mobile.

- Maintenabilité

L'utilisation des microservices peut rendre de gros logiciels plus maintenables. Il permet en effet d'éviter de devoir gérer un volume de code trop important. Leur facilité de maintenance peut les rendre avantageux financièrement parlant.

- Résilience

Pour chaque service contenant au moins un processus, l'interruption d'un service n'empêchera pas les autres de fonctionner. L'application n'est soit plus en marche, soit interrompue, mais peut être dans des états intermédiaires. Cela permet donc de réduire le temps où l'application est inutilisable dans son ensemble, au profit d'un moment où l'application fonctionne partiellement, et peut dans la plupart des cas répondre aux besoins du client.

- Scalabilité

La plupart du temps, une partie de l'application nécessite plus de ressources que le reste. Dans le cas d'une application monolithique, il faut augmenter les ressources utilisées pour toute l'application.
Les microservices n'ont pas ce problème, puisque chaque service se voit accorder des ressources de manière indépendante. Il est donc tout à fait possible d'augmenter les ressources uniquement pour les services concernés. Les microservices permettent donc d'avoir une gestion plus fine des ressources disponibles et peuvent réduire le coût d'une montée en charge verticale. Aussi, ajouter de nouvelles fonctionnalités à une application basée sur les microservices se fait simplement en ajoutant de nouveaux services.

- Testabilité

Chaque microservice n'étant responsable que d'une fonctionnalité, il est plus facile de le tester ; la simplicité des services aide à leur testabilité. Des difficultés pourront cependant arriver en testant les interactions entre les différents services. Si l'API testée a été bien définie, cela ne devrait pas être un problème.

IV - Conditions d'utilisation

Les microservices nécessitent la modernité de l'organisation et des technologies employées. Pour les utiliser de la manière la plus optimisée possible, il est important de parler de déploiement et d'organisation humaine.

IV-A - Déploiement

Le nombre important de services peut poser des problèmes de déploiement. Si tel est le cas, il faut les résoudre au plus vite afin de faciliter l'avancement du projet et de pouvoir profiter de manière efficace des avantages de ce genre d'architecture. Nous avons souvent recours au déploiement continu, pratique visant à réduire le plus possible le temps de cycle, c'est-à-dire le temps écoulé entre l'écriture d'une nouvelle ligne de code et l'utilisation réelle de ce même code par des utilisateurs finals.

L'équipe s'appuie sur une infrastructure automatisant l'ensemble des étapes de déploiement (ou « mise en production »), de sorte qu'après chaque intégration qui se solde par des tests réussis, notre application est mise à jour. La meilleure des pratiques à adopter dans ce cas-là est de développer une culture de l'automatisation.

Pour avoir plus de détails sur la manière de pouvoir gérer tous ces déploiements, on peut s'appuyer sur le DevOps, le continuous deployment, le continuous delivery et le continuous integration, le but étant d'être capable de livrer rapidement une application à faible coût, et cela importe plus que la méthode employée.

IV-B - Hébergement peu coûteux

Pour faire des microservices, il faut déployer beaucoup plus d'applications indépendantes que pour une application monolithique. Si des mécanismes ne sont pas mis en place, les microservices deviendront vite beaucoup trop chers par rapport à leur bénéfice.

Les services peuvent être hébergés sur le même serveur, mais ceci est généralement considéré comme une mauvaise idée, car contribuant à un couplage matériel fort. Si l'on veut héberger tous nos services de manière indépendante, il n'est toutefois financièrement pas judicieux d'acheter un serveur physique pour chacun. Il faut donc penser à utiliser des technologies de virtualisation, des conteneurs logiciels, ou du cloud.

Par exemple, Docker, grâce à sa vitesse, est particulièrement adapté pour mener à bien les nombreux déploiements.

IV-C - Erreurs à éviter

Des erreurs sont souvent commises par les débutants. Nous allons en citer quelques-unes avec des suggestions de solution.

IV-C-1 - Découpage

Découper une application monolithique en microservices n'est pas chose facile. Si l'application est mal découpée et que les microservices ne sont pas bien modélisés, cela peut créer beaucoup de problèmes, notamment de couplage.

Par exemple, dans le cas où nous avons dès le début de nombreux services, cela peut engendrer des difficultés de déploiement.

Maladroitement, certaines équipes de développement débutantes en microservices découpent et redécoupent l‘application en services jusqu'au point où chaque méthode est isolée dans un « nanoservice ». Dans ce cas, les résultats des tests seront mauvais. Les échanges entre ces « nanoservices » seront extrêmement complexes, donc difficiles à comprendre et à surveiller, les performances seront mauvaises et le nombre de serveurs nécessaires sera important. Finalement, les inconvénients finissent par surpasser les avantages. Plus les services sont découpés finement, plus le système sera lent. Enfin, la multiplication trop importante des services finit par rendre très difficile la surveillance du système.

Il y a donc un équilibre à trouver dans le découpage, de manière à obtenir une granularité optimale. Nous pensons qu'il faut à la fois s'assurer qu'aucun service ne soit trop grand au point de nécessiter une équipe d'une dizaine de personnes pour sa maintenance, et que chaque service corresponde bien à une fonctionnalité métier différente des autres.

IV-C-2 - Monitoring

Pouvoir observer le comportement de chaque service est très important (consommation de données, appels réseau, erreurs, etc.). Chose qui peut s'avérer très facile quand le système ne compte que quelques services, mais quand les services se multiplient et les connexions entre eux également, il devient très difficile de tout superviser.

Pour superviser ces services, il faut utiliser des logs ; pour localiser un log, l'équipe doit vérifier chaque microservice, mais cela peut vite s'avérer très compliqué quand le système compte de nombreux microservices. Il faut aussi penser à localiser les erreurs en cas de défaillance du système.

Une des solutions est d'avoir un système de logs centralisé qui permet de voir de quel service vient un log. De cette façon l'équipe peut savoir d'où viennent les erreurs et de les régler dans les plus brefs délais.

IV-C-3 - Difficulté de la définition des microservices

Il peut arriver que les tests d'intégration se passent mal à cause du manque de communication entre les personnes ayant développé les modules. Ce n'est pas un problème propre aux microservices, mais à la multiplication des modules, et le fait qu'il existe des frontières avec les fonctions métier. On peut demander à l'équipe créant le microservice de créer des stubs (dans le cas où une bibliothèque cliente a également été développée), mais cela ne marchera pas si les technologies utilisées sont trop hétérogènes. On pourrait aussi demander à l'équipe de faire une sorte de service stub, répondant à la même API que le microservice, mais qui envoie des données factices.

Les tests doivent être créés par l'équipe écrivant le microservice puisqu'il doit s'agir d'un projet indépendant, car si une autre équipe met en place les tests, le risque de se tromper est grand. On peut créer des mocks pour simuler l'existence d'un microservice, mais il faut bien sûr vérifier qu'il est bien appelé par les clients. Pour que ces tests soient utilisables par tous, on peut imaginer développer un serveur de mocks avec une API similaire au service. Celui-ci serait ensuite lancé par les clients lors des tests.

Cette méthode a l'avantage de pouvoir être appelée par n'importe qui, mais cela risque d'être trop lent en pratique si l'on doit l'utiliser à chaque test unitaire, à cause des appels réseau (même vers la même machine) qu'elle provoque.

V - Du monolithique aux microservices

Amazon et Netflix sont des entreprises parmi d'autres qui ont transformé leurs applications monolithiques en des applications en architecture microservice. Passer d'une application monolithique aux microservices est ainsi la manière la plus recommandée de mettre en place des microservices, certains allant jusqu'à dire que c'est la seule manière correcte.

L'idée est de prendre une application existante, de taille considérable, et de la découper progressivement en différents services. On peut également ajouter des nouvelles fonctionnalités en développant de nouveaux services si nécessaire.

Une application monolithique est relativement simple à découper en microservices comparé à d'autres changements dans une architecture. Cette approche a l'avantage de ne pas attendre qu'une application soit trop grande pour pouvoir profiter des bénéfices des microservices. La migration peut se faire de manière relativement simple par rapport à un autre changement d'architecture.

Cette option est utile quand le volume de code en question est tel qu'il devient un obstacle à sa maintenance et à son déploiement rapide. Passer à une application en microservices peut également être intéressant dans le cas où le temps entre chaque déploiement est trop long.

Il est souvent nécessaire de découper l'application progressivement, afin d'atteindre un bon découpage et de permettre une adoption progressive des microservices. Ceci implique que les bénéfices seront eux aussi progressifs. Il faut également penser aux changements à opérer côté organisation et habitudes des équipes ; tout ceci peut prendre du temps avant d'être opérationnel.

Cette option permet aux différentes parties d'une entreprise de communiquer entre elles facilement, en partant du principe qu'elles utilisent toutes des microservices. Il est important de se souvenir de ce qui a poussé l'architecte à utiliser l'architecture actuelle avant d'en changer, pour ne pas risquer de finir avec une application qui ne répond plus aux besoins des utilisateurs.

VI - Les microservices pour une nouvelle application

Les microservices peuvent aussi être utilisés dans une nouvelle application. Des questions doivent cependant être posées.

Utiliser directement les microservices demande en effet d'avoir une bonne connaissance métier du client afin de pouvoir effectuer un découpage adéquat. Cela demande en outre du temps, ce qui risque de ralentir les développements, alors que la plupart des bénéfices ne seront pas visibles immédiatement.

Nous pouvons donc commencer par faire une application monolithique, qui sera par la suite découpée une fois devenue trop grande.

VII - Conclusion

Les microservices permettent une organisation décentralisée, en petites équipes, fonctionnant indépendamment les unes des autres, et permettant donc d'éviter la plupart des gros problèmes que peuvent rencontrer les projets de taille importante.

Il faut bien prendre en compte les contraintes des microservices afin de pouvoir faire un bon choix. Les microservices sont naturellement adaptés aux applications (qui peuvent être facilement déployées par le client) de taille importante, et qui seront régulièrement mises à jour. Il ne faut pas oublier que les microservices sont une architecture distribuée et que pour accéder à la partie métier de l'application, il est nécessaire d'être relié d'une manière ou d'une autre au réseau contenant les microservices nécessaires à l'utilisation de l'application.

On peut essayer de reproduire l'organisation des microservices dans d'autres types d'applications. Cependant, ce n'est pas sans risque. En effet, cela demande plus de rigueur de la part des développeurs ; il devient plus difficile d'assurer l'indépendance de ses différentes parties sans oublier de prévoir la capacité de les déployer régulièrement.