Huit bonnes pratiques pour bâtir une architecture en microservices

Huit bonnes pratiques pour bâtir une architecture en microservices Le point sur quelques recommandations clés. Un tour d'horizon portée par deux spécialistes, l'un travaillant pour 20 Minutes, l'autre pour TF1+.

Les applications reposant sur des architectures en microservices sont devenues légion en quelques années. Reste à savoir quelles bonnes pratiques mettre en place pour ce type d'environnement logiciel.

1. Partir de domaines fonctionnels

En amont, les applications seront découpées en domaines métier. "Dans les médias, on aura par exemple des domaines en charge de la préparation des vidéos, du player, de la gestion des métadonnées ou du pilotage des utilisateurs", note Olivier Mansour, architecte chez Theodo et CTO advisory services pour TF1+. A chaque domaine sera dédiée une équipe chargée de développer et maintenir les microservices sous-jacents. Pour un player vidéo, il s'agira de services d'autorisation ou encore de delivery pour gérer les formats adéquates, notamment.

Pour Olivier Mansour, la première raison qui motive le choix d'une architecture en microservices réside dans la gestion du passage à l'échelle de l'équipe de développement. "Plus l'équipe sera importante, plus la logique en domaines et microservices sera pertinente", constate l'architecte. "Si elle ne compte que quelques développeurs, ce sera une erreur de partir dans cette voie. On prendra en pleine face le coût et la complexité des microservices sans bénéficier de leurs gains."

2. Procéder par étape

Dans le cas d'une start-up qui débute, il est conseillé de commencer par une application monolithique. Suite à une ou plusieurs levées de fonds, la jeune pousse pourra ensuite passer rapidement de quelques développeurs à plusieurs dizaines voire plusieurs centaines. "C'est là que la logique de travail en microservices prend tout son sens", insiste Olivier Mansour. "On basculera alors dans une phase de découpage applicatif via l'extraction de domaines et de fonctionnalités qui permettra d'embarquer de nouvelles équipes avec une structure de gouvernance cadrée."

3. Eviter de sur-découper

"Toute la question est de savoir jusqu'où aller en termes de découpage", souligne Olivier Mansour. Chez 20 Minutes, un microservice se présente sous la forme d'une petite tâche précise et répétitive encapsulée dans une fonction Amazon Lambda. Il peut s'agir par exemple de gérer l'envoi d'e-mails ou de notifications. Ou encore de gérer des photos, depuis leur enregistrement dans la médiathèque du site jusqu'à la génération de métadonnées par reconnaissance d'image en passant par le recadrage des portraits sans couper les têtes des sujets. D'autres microservices prennent en charge la gestion des blocs sur les pages, etc.

Globalement, un microservice ne devra être ni trop fin ni trop volumineux. "Souvent, on crée un microservice pour répondre à un nouveau cas d'usage. Avant de se lancer bille en tête dans ce développement, il faudra d'abord se demander si une fonction existante peut absorber le cas d'usage ciblé", conseille Aurélien Capdecomme, CTO de 20 Minutes. "En cas de fonction trop volumineuse, on pourra être amené à la découper en sous-services."

4. Prioriser les échanges standards

Les échanges entre microservices devront être suffisamment neutres et standardisés. Objectif : faciliter le remplacement d'un microservice par un autre, voire l'ajout d'un nouveau.

"Chez 20 Minutes, nous cherchons à laisser un maximum de portes ouvertes pour nous permettre de venir brancher de nouvelles fonctions au regard de l'évolution des besoins", commente Aurélien Capdecomme. "En 2020, nous avons par exemple développé une fonctionnalité d'analyse de texte pour suggérer des tags au regard du contenu des articles. Cette fonction a été conçue dès le départ pour accueillir de nouvelles possibilités. Ce qui a été le cas il y a quelques mois via l'IA générative avec une fonctionnalité de résumé d'articles." Et Olivier Mansour d'ajouter : "Les microservices pourront fonctionner de manière autonome pour peu qu'ils respectent leur contrat d'interface."

5. Eviter les surdépendance

Reste que l'évolution d'une fonctionnalité pourra tout de même avoir un impact sur l'évolution d'un ou plusieurs microservices. Ce qui implique de coordonner potentiellement autant d'équipes différentes au sein d'une feuille de route commune. "C'est notamment un cas de figure qui se présente quand un microservice se positionne en fournisseur d'un autre, par exemple lorsque l'ouverture d'une nouvelle fonctionnalité dépend d'une authentification à double facteur", précise Olivier Mansour. "Dans certains cas, un microservice pourra être tributaire de toute une myriade de microservices tiers. Ce qui est à proscrire au risque de se retrouver dans une situation proche d'un monolithe."

La question de l'architecture se révèle par conséquent centrale. D'un seul monolithe à piloter, on passe à N services à gérer. "Ce qui implique une forte problématique DevOps. On ne peut pas en effet s'orienter vers une architecture en microservices sans autonomiser les développeurs sur la création de leur infrastructure, chacun ayant sa base de données à maintenir", poursuit Olivier Mansour. "La surveillance des systèmes est également bien plus complexe. Elle implique de s'outiller en solutions d'observabilité de manière à centraliser les logs, les traces et les métriques et bénéficier d'une vue d'ensemble pour remonter à la source des problèmes."

6. Architecturer ses microservices

L'architecture de l'application est fondamentale. L'application mobile de 20 Minutes passe par exemple par un microservice unique pour lancer ses appels en base de données. "Et ce pour favoriser la maintenabilité des appels, mais aussi pour des raisons de sécurité. En cas de multiplication des flux, on multiplie aussi le risque de bugs", souligne Aurélien Capdecomme.

Si l'architecture est bien conçue, un incident n'impactera pas l'ensemble de la stack. "Il s'agit du principal avantage comparé à une application monolithique qui cédera dans son intégralité en cas de pic de trafic trop important. Avec les microservices, on répartit la charge et on ajuste la puissance machine pour chacun d'eux", reconnaît Aurélien Capdecomme. Et Olivier Mansour d'ajouter : "A chaque microservice pourra être allouées des ressources machines ad hoc ou encore un CDN en fonction des pointes de trafic. Si la charge ne peut être encaissée, certains microservices de moindres importances pourront être désactivés pour permettre à la plateforme de continuer à fonctionner. Dans le cas d'un site média, il pourra s'agir par exemple de désactiver la personnalisation pour permettre au player vidéo retransmettant un grand événement sportif de continuer de fonctionner."

7. A chaque domaine applicatif sa base de données

Au sein d'une architecture en microservices, une structure de données devra être en principe allouée à chaque domaine applicatif. "On aboutira à un grand nombre d'instances de base de données. Ce qui provoquera des problématiques nouvelles, notamment en termes de rationalisation de l'exploitation des coûts", complète Olivier Mansour. "Mais ce patern permettra par exemple à un service de géolocalisation de fonctionner en toute autonomie."

8. Etre cohérent en termes de technologies

Deux microservice développés dans des langages différents pourront tout à fait dialoguer ensemble. "Au sein de 20 minutes, nous préférons néanmoins programmer l'ensemble de nos fonctions dans un langage unique, à savoir NodeJS. Ce qui permet de rationaliser les équipes en termes de formation et de recrutement, mais aussi d'appliquer les mêmes standards et librairies de sécurité, les mêmes règles et les mêmes normes de codage", note Aurélien Capdecomme.

A chaque appel de microservices, il est recommandé de réaliser des contrôles. "A chaque étape, il faudra vérifier que le service qui interroge le suivant a bien l'autorisation de le faire", insiste pour finir Aurélien Capdecomme.