Publié par
Il y a 3 années · 15 minutes · Back

Microservices – Les concepts

Microservices. C’est une architecture dont on entend beaucoup parler, mais que se cache-t-il derrière ce terme ?

Avec une série de trois articles, nous allons tenter de découvrir ce qu’est une architecture microservices et ce qu’elle change par rapport à une architecture « classique ».

Un SI est un système complexe qui se développe, évolue, vit et meurt. A la manière d’un être vivant, un SI est un assemblage de plus petites unités qui fonctionnent de concert et qui se répartissent des fonctions clés au sein du système. De nombreux styles d’architectures permettent de réaliser de tels systèmes.

Nous proposons, dans cet article, de découvrir les architectures microservices et plus précisément les concepts qui s’y rattachent. On tâchera de comprendre ce qui se cache derrière cette dénomination qui, au premier abord, doit se comprendre comme ceci : un système complexe de petits services simples. Nous verrons également comment ce style d’architecture répond aux différents besoins du SI.

Nous avons évoqué un assemblage de petites unités au sein d’un système complexe. Ces petites unités, vous l’aurez compris, constituent lesdits services d’une architecture microservices. Quelles sont les concepts qui se cachent derrière ces services ?

Des unités fonctionnelles du système

Un microservice est avant tout une unité fonctionnelle. Il correspond à une fonctionnalité précise, logique et cohérente du système. Un microservice est donc autonome vis à vis de la fonctionnalité qu’il réalise. Il a son propre code, gère ses propres données et ne les partage pas – pas directement en tout cas – avec d’autres services.

Dans ce style architectural un service correspond, de plus, à un processus système indépendant. Dans certains cas, un microservice peut être constitué de plusieurs processus mais l’inverse n’est pas vrai. Une conséquence de ce constat est que les services communiquent entre eux par des appels réseaux et non par des appels de fonctions en interne dans un processus.

Un microservice est donc une unité de service fonctionnelle qui se développe, se déploie, s’exécute et gère ses données indépendamment des autres services du système. Quels sont les bénéfices de ce découpage en services ?

La modifiabilité avant tout

Lorsqu’une fonctionnalité précise du SI doit être modifiée, l’évolution en question ne porte que sur le code d’un service en particulier. Cela implique que les autres services ne sont pas directement impactés. Ainsi, la modification du code ou des données d’un service provoque uniquement la mise à jour et le redéploiement d’un service car celui-ci s’exécute dans un processus isolé. Il n’y a, de plus, pas d’obligation d’embarquer des mises à jour d’autres fonctionnalités qui auraient été intégrées en parallèle à l’évolution de la fonctionnalité, car le code est séparé. De la même façon, la présence d’une anomalie sur une fonctionnalité ne bloque pas l’évolution ou le déploiement d’une autre fonctionnalité.

On peut, grâce à ces caractéristiques, facilement envisager de prototyper, déployer et tester une nouvelle fonctionnalité sans remettre en cause tout le système. Le système est comme un assemblage de pièces de LEGO. Une brique ou une autre peut être ajoutée ou retirée facilement.

Le système est construit à une échelle qui permet de modifier une fonction du système sans avoir peur de créer des effets de bord sur d’autres fonctions. Dans cette architecture, l’échelle de la modification est donc, non pas un ensemble de fonctionnalités assemblées dans une “application”, mais la fonctionnalité, portée par le service. Cette échelle de la modification confère d’autres avantages.

Une architecture à l’échelle du service

S’agissant de processus isolés, l’augmentation ou la diminution des ressources allouées à un service ou un ensemble particulier de services peut se faire de manière indépendante. On peut choisir individuellement les services dont on veut modifier le nombre d’instances. L’unité de mise à l’échelle est bien réduite au service et non pas à une “application” ou un ensemble technologique de fonctions.

Chaque service est différent et sert des besoins différents. Chaque service a donc son propre cycle de vie et in fine une durée de vie qui lui est propre. Là encore la granularité de déploiement et d’exécution d’un service permet de contrôler le cycle de vie d’une fonction de manière indépendante des autres fonctions du système. Un service peut ainsi être suspendu ou remis en fonction indépendamment.

Selon le même principe, les données d’un service peuvent aussi être mises à jour, migrées, traitées sans risquer d’impacter les autres fonctionnalités du système. Dans une architecture microservices chaque service est différent et évolue donc selon son propre rythme.

Les services sont donc autonomes mais fonctionnent tout de même de concert entre eux, car ils forment un système fonctionnel et cohérent dans sa globalité. Cela est possible par une communication à base de messages.

Des services et des messages

Une architecture microservices est avant tout un système de services qui communiquent entre eux. Comme on vient de l’évoquer, chaque service réalise une fonction précise dans un système. Chaque fonction a néanmoins besoin d’être déclenchée, régulée ou inhibée par d’autres fonctions. Pour y parvenir les services échangent, par le biais d’interfaces qui leurs sont propres, des messages entre eux.

Je ne suis que le messager

Dans ce style architectural, le vecteur de la communication se contente de transporter les messages entre les services. Il n’y a pas de transformation, agrégation ou enrichissement des messages. Autrement dit, il n’y a pas “d’intelligence” dans le vecteur. Cette intelligence, si nécessaire, est bien sûr portée par les services qui réalisent les fonctions. Le vecteur ne sert que de tuyau et est “aveugle” vis-à-vis du contenu des messages. Il peut par conséquent être quelconque mais est avant tout focalisé sur son rôle premier : véhiculer des messages de manière fiable.

Deux modes de communication sont couramment employés dans ce style d’architecture. On retrouve, sans surprise, une communication de type REST qui s’appuie généralement sur le protocole HTTP et une communication de type BUS qui centralise les échanges de messages. L’utilisation de ces deux modes de communication dans une architecture microservices sera étudiée dans le prochain article.

Le contenu des messages n’est pas pollué par une multiplication d’enveloppes techniques. Les messages véhiculent une information pertinente destinée à la réalisation des fonctions des services. Les mises à jour d’interfaces sont en ce sens plus souples, car elles portent sur une modification de contenu imposée par la modification d’un service et non sur une modification liée aux enveloppes techniques.

Dans le cas général, un service consomme en entrée des informations d’autres services et produit en sortie des informations qu’il communique à son tour à d’autres services. La communication d’un service en amont peut être rendue fortement dépendante d’un nombre important de services en aval. La communication est donc prioritairement asynchrone. Chaque service pouvant poster un message et écouter des messages d’autres services au fur et à mesure de leur disponibilité. Le synchronisme de communication entre services augmente les sources de pannes et de lenteurs, qui se répercutent directement sur les services en amont.

Une architecture microservices tend donc plutôt vers une architecture réactive, à base d’évènements, déclenchés et écoutés par les services. Pour que ces échanges entre services puissent s‘établir, ils doivent toutefois démontrer une certaine tolérance.

Des services tolérants

Si une catastrophe peut arriver, elle finira obligatoirement par arriver

Des services seront indisponibles, des données seront manquantes, peut-être même incohérentes. Des services peuvent être volontairement éteints, remplacés ou mis à jour. Tous ces aléas font la vie d’un SI. Plutôt que de chercher à se protéger, par le rejet, de ces problèmes qui se produiront invariablement, l’architecture microservices privilégie plutôt la tolérance et l’adaptation.

Chaque service est conçu au sein d’un système avec ses interactions. Il est également conçu en étant conscient que les services dont il dépend ou qu’il influence peuvent être indisponibles. Un service adapte donc son fonctionnement en fonction de l’état du système dans lequel il évolue. Cela se traduit par exemple par une remontée d’alertes, un fonctionnement en mode dégradé ou encore par une reprise de fonctionnement lors du retour à une situation nominale.

Cette acceptation de la panne va au-delà des dépendances entre services. Chaque service doit être conçu pour tolérer par exemple une donnée manquante ou incohérente. Cela suppose une certaine souplesse des interfaces. Un service doit tolérer, par exemple, des messages même s’ils comportent des données dont il n’a pas besoin. D’un autre côté un service doit pouvoir fonctionner dès lors qu’un message comporte les données suffisantes à son fonctionnement et tolérer l’absence d’informations optionnelles. Dès lors qu’une rupture du contrat envers un client est obligatoire pour l’évolution d’un service, on peut par exemple, envisager la coexistence de versions différentes du service pendant la période de migration des services consommateurs.

Les services sont donc tolérants vis-à-vis de leurs échanges en messages. Cette tolérance implique tout de même une certaine surveillance du système.

Un système sous surveillance

Le système doit être, en effet, en permanence surveillé. Même si les services sont tolérants à des pannes, celles-ci peuvent compromettre le fonctionnement du système global. Il est donc important d’être capable de détecter rapidement une panne dans le système pour pouvoir intervenir rapidement : remettre en route, corriger une défaillance, redémarrer un service sur une autre machine, augmenter le nombre de ressources en cas d’un pic de trafic, de lenteur ou de saturation d’un service. Il s’agit là d’une surveillance technique du bon fonctionnement du système.

Il est également vital de surveiller le système et les services d’un point de vue fonctionnel. Le bon fonctionnement du système passe par la surveillance d’indicateurs métiers : transactions validées, en erreur, quantité de commandes, envois de messages en erreur, nombre d’inscriptions, etc. Tous ces indicateurs métiers sont les premiers révélateurs d’un problème. Ils peuvent également aider à distinguer les fonctions du système les plus sollicitées de celles qui sont inutilisées.

Dans une architecture microservices la surveillance est d’autant plus importante que les services sont nombreux et les communications complexes. Cette complexité nécessite et reflète bien sûr une organisation, humaine notamment, à l’origine de ces architectures.

Des équipes centrées autour d’un objectif

Une équipe qui sait ce qu’elle fait et pourquoi, le fait bien.

Tout comme un service se concentre sur la réalisation d’une fonction, les équipes s’organisent autour de fonctionnalités métier et non pas de technologies. Les équipes sont multidisciplinaires et se complètent pour la réalisation d’un objectif commun : faire fonctionner un système.

You build it, you run it

La surveillance que l’on évoquait précédemment fait partie intégrante du rôle de cette équipe. Il ne s’agit pas d’un rôle porté par une équipe distincte et dédiée. Le service est donc avant tout un produit, issu d’une équipe, qu’elle s’approprie, réalise et accompagne durant toutes les étapes de la vie du produit.

L’appropriation du produit passe également par la taille des équipes. Un service est d’autant plus facile à s’approprier qu’il est petit, par définition, mais aussi que le nombre de personnes qui en sont responsable est petit.

De la même manière que les équipes sont diversifiées dans leurs rôles, leurs objectifs et leurs compétences, les services et les technologies dont ils sont composés le sont aussi.

Des services diversifiés

Une équipe qui utilise des outils adaptés, le fait mieux.

Nous l’avons déjà vu, chaque service répond à un problème particulier. Il n’y a donc a priori pas de raison d’adresser des problématiques différentes avec une seule et même pile technologique.

Chaque technologie ou outil est plus adapté à résoudre un certain type de problème. Avoir la possibilité d’utiliser un outil adapté à la résolution d’un problème est donc un facteur de succès pour la mise en place d’un service. Par ailleurs, l’isolation des services permet de basculer facilement d’une technologie à une autre.

Cela va également dans le sens d’équipes responsabilisées qui choisissent les outils qu’elles utilisent et qu’elles sont le plus à même de juger pertinents.

Un facteur de succès qui se révèle également important après cet aspect sur la diversification est bien sûr la qualité.

Des procédures automatisées, des services de qualité

On vient de voir que chaque service est façonné avec des outils adaptés et donc diversifiés.

Cela implique dans un premier temps que la qualité des services doit être mesurée en permanence : tests automatisés et analyse du code – intégration continue. Par ailleurs l’aspect “système complexe” de cette architecture, implique que les tests d’intégration et les tests globaux, sont aussi importants que les tests des services isolés. Ils ont donc tout autant vocation à être automatisés.

Cela implique ensuite, pour la viabilité du système en production, que les déploiements sont au maximum automatisés – déploiement continu. Les procédures doivent être reproductibles, répétables et doivent contenir le moins de sources d’erreurs possible – intervention manuelle notamment – car elles seront potentiellement jouées un grand nombre de fois.

Conclusion

La seule chose qui ne change pas, c’est le changement

Les SI changent. Certaines fonctionnalités sont volatiles, d’autres persistantes, d’autres encore sont testées puis abandonnées et quelques unes sont fréquemment modifiées. En d’autres termes le SI réagit en permanence à des besoins changeants et ces changements sont de plus en plus fréquents. L’architecture mise en place est donc fortement contrainte sur sa dimension “modifiabilité”.

Nous venons de voir que les architectures microservices adressent directement cette problématique de la modifiabilité. L’échelle de l’architecture est la fonctionnalité, le service. Cela rend possible une dynamisation de l’architecture à l’échelle de la fonctionnalité. Les fonctionnalités sont en effet isolées les unes des autres au sein du système.

Cette isolation à des revers. Elle implique notamment une communication plus pertinente, organisée autour de messages, mais aussi plus coûteuse. Pour la viabilité du système dans sa globalité, les services doivent être tolérants à des défauts d’autres services et de leurs messages. Le système doit être également surveillé, aussi bien sur des aspects techniques que fonctionnels.

Les organisations à l’origine de ces architectures doivent également refléter le système en lui-même (i.e. la loi de Conway). Les équipes et les services sont diversifiés et organisés avant tout autour des fonctionnalités du système et pas des technologies.

Un second revers de cette organisation décentralisée concerne la complexité de la compréhension du système dans sa globalité. On peut certes comprendre le fonctionnement d’un service isolé, mais il faut aussi et surtout être capable d’intégrer son fonctionnement dans l’ensemble du système.

Une difficulté se situe aussi dans la définition même des services et des fonctions qu’ils réalisent. Cette définition n’émerge pas nécessairement immédiatement et peut faire l’objet d’ajustements progressifs.

De nouvelles possibilités sont donc offertes par cette architecture à l’échelle de la fonctionnalité. Mais des pièges, à éviter, émergent tout de même des quelques concepts que l’on vient de dégager. Ces pièges doivent bien sûr être spécifiquement adressés dans le cadre d’une architecture microservices.

Nous verrons, dans le prochain article de cette série, des exemples possibles d’architectures microservices. Les pièges de ces architectures, feront quant à eux, l’objet du dernier article.

Références

http://martinfowler.com/articles/microservices.html

http://www.infoq.com/fr/news/2015/02/microservices-sharing-code

https://blog.yourkarma.com/building-microservices-at-karma

http://www.javaworld.com/article/2863409/soa/why-2015-will-be-the-year-of-microservices.html

http://www.infoq.com/news/2014/05/microservices

 

Sergio Dos Santos
Craft / DevOps / Back / Front / Cloud

11 réflexions au sujet de « Microservices – Les concepts »

  1. Publié par Anas, Il y a 3 années

    Concernant les concepts « La modifiabilité avant tout », « Des services et des messages », « Des services tolérants », « Un système sous surveillance », « Des services diversifiés » et « es procédures automatisées, des services de qualité », on reste dans les concepts SOA classiques avec :
    – une orientation pour l’asynchronisme (qui était un des critères d’agilité du SI et de maturité SOA même s’il n’a pas été l’implémentation la plus courante).
    – un cloisonnement des donnée au sein d’un seul système fournisseur de référence (qui n’est pas autre chose que les préconisation d’urbanisations et d’Architecture d’Entreprise … encore eux  )
    C’est toujours bien de changer de vocabulaire, mais attention à ne pas refaire la poudre en définissant de concepts déjà existants et à l’œuvre  .
    Concernant les concepts « Des unités fonctionnelles du système », « Une architecture à l’échelle du service » et « Des équipes centrées autour d’un objectif », là ça devient intéressant car ça re-pose la question de la granularité d’une fonction (… et oui, la question et vielle comme le monde et récurrente à chaque vague technologique ou néo-architecturale).
    Qu’est-ce qu’une « unité fonctionnelle », une « fonctionnalité précise, logique et cohérente du système » ?
    Est-ce une tâche automatique (*) ou un ensemble cohérent de tâches automatiques (ex : API) ?
    Les équipes étant taillées sur l’unité fonctionnelle, la granularité des fonctions sera un sujet central de débats car il impactera fortement l’organisation. Pour convaincre les sponsors, il faudra être capable de démontrer que l’organisation en microservice n’engendre pas de doublons et par conséquent travailler en étroite collaboration avec la cellule d’urbanisme ou d’architecture d’entreprise (… purée encore eux  ).

    (*) Par « tâche automatique » j’entends un traitement automatique produisant un résultat ayant une valeur ajoutée métier, autrement dit un traitement produisant une donnée métier ou changement d’état d’une donnée métier ou un effet de bord ayant un sens métier (ex : méthode POST de création d’une commande d’une API REST de gestion de commandes).

  2. Publié par Michel Hubert, Il y a 3 années

    On remplace SOAP/XML par REST/JSOn, on remplace web service par micro services et on est reparti pour 10 ans :)

  3. Publié par Anas, Il y a 3 années

    T’es un peux trop dur :-)

    Il y a quand même des différences notables:

    – L’architecture REST a forcé les architectes techniques à construire des services autour de ressources et par conséquent autour d’objets métiers, ce qui a eu comme effet de se rapprocher des préconisations d’urba/EA.

    – Les concepts « Des unités fonctionnelles du système » est instauré comme règle d’architecture technique ce qui va forcer les projets à cloisonner certaines données métiers au sein d’un seul système fournisseur de référence.

    Finalement c’est une bonne chose que des préconisations d’urba\EA se soient retrouvées gravées sur le marbre sous forme de modèle d’architecture technique.

    Une question reste cependant en suspend:
    Au sein d’un microservice, quelles données métier cloisonner et quelles données métier échanger ? Quels sont les critères d’arbitrage ? .

  4. Publié par Sergio Dos Santos, Il y a 3 années

    L’architecture microservices n’est pas en contradiction avec l’architecture orientée services. Au contraire les architectures microservices incarnent une forme particulière, une certaine évolution des architectures orientées services suite à un retour d’expérience.

    Le constat avec les architectures orientées services est que l’unité de déploiement est dans la majorité des cas une application monolithique, qui regroupe différents services qui réalisent eux-même plusieurs fonctions. En pratique, quand on modifie un service on modifie en réalité toute l’application et donc un ensemble de services et de fonctions. Idem pour les données groupées dans une seule base et qui concernent pourtant des services différents et donc des représentations de l’information différentes. Même problématique au niveau des outils et de la façon de faire : le regroupement de services au sein d’une application limite et contraint les choix technologiques des services qui deviennent bien souvent dépendants d’un ensemble technologique prédéfini.

    Dans une approche microservices chaque service est séparé du point de vue code, données, déploiement et exécution. C’est un concept qui émerge en réponse à ces problématiques et fait bénéficier aux architectures microservices d’une plus grande souplesse en termes d’évolution, de diversification. A cette isolation au niveau processus est donc invariablement associée une communication à base de messages, tolérante et adaptative, une automatisation et une mesure de la qualité (cf. l’article).

    Il ne s’agit donc pas de réinventer les architectures orientées services – l’héritage est bien visible – mais simplement de dégager les concepts qui se révèlent particulièrement importants sous cette forme d’architecture orientée services : un système complexe de plusieurs « petites unités fonctionnelles ».

    Et c’est vrai que toute la difficulté réside dans ce découpage de « l’unité fonctionnelle ». Dans les références il y a pas mal d’idées sur cette problématique du découpage. Il y a notamment l’idée que le code de l’unité doit être suffisamment petit pour être rapidement compris ou remplacé. Une autre idée est que ces unités peuvent émerger d’elles même au fur et à mesure de la vie du système. Un service qui réalise une fonction peut être amené à s’enrichir jusqu’au point où l’équipe réussit à identifier et isoler des fonctions distinctes (cf. https://blog.yourkarma.com/building-microservices-at-karma). Cette démarche peut également s’appliquer lors de la migration d’une application monolithique vers un système de microservices.

  5. Publié par Sophie, Il y a 3 années

    Bonjour,
    Merci pour votre article très clair.
    Pensez-vous que l’architecture Microservices est un pré-requis au concept du « new IT operating model: Broker/Integrate/Orchestrate. »?

  6. Publié par Sergio Dos Santos, Il y a 2 années

    Bonjour Sophie,

    Je ne connaissais pas bien le modèle Broker/Integrate/Orchestrate. Néanmoins après avoir lu quelques articles sur le sujet je trouve qu’il y a des objectifs que l’on retrouve en commun : aligner le SI aux besoins en fluidifiant son évolution et le faire vivre en production en mesurant son activité et la complétude de ses objectifs.

    Il y a en revanche un point sur lequel l’approche diffère. J’ai l’impression que le modèle Broker/Integrate/Orchestrate est « dépendant » des solutions disponibles sur le marché. L’approche microservices est, elle, pilotée uniquement par les besoins en fonction desquels dérivent des solutions.

    L’approche microservices est donc compatible avec le modèle Broker/Integrate/Orchestrate tout en lui ouvrant en plus la voie du « sur-mesure » quand nécessaire.

  7. Publié par T, Il y a 2 années

    @Anas: « L’architecture REST a forcé les architectes techniques à construire des services autour de ressources et par conséquent autour d’objets métiers, ce qui a eu comme effet de se rapprocher des préconisations d’urba/EA. »

    Tout comme Corba (1992) qui se concentrait sur les objets métiers :) Le monde de l’intégration est certes en perpétuel mouvement mais souvent on ne fait que recycler du matériau de base avec seulement une petite couche de vernis.

    Très bon article btw.

  8. Publié par Gilles Perreymond, Il y a 2 années

     » Dans ce style architectural un service correspond, de plus, à un processus système indépendant. Dans certains cas, un microservice peut être constitué de plusieurs processus mais l’inverse n’est pas vrai. Une conséquence de ce constat est que les services communiquent entre eux par des appels réseaux et non par des appels de fonctions en interne dans un processus.  »
    Je suis 100% en accord avec cette définition.

    Le meilleur découpage devra prendre en compte non seulement les besoins à un instant (t) mais surtout laisser des portes ouvertes à un redécoupage ultérieur.

    Un microservice qui devient consommateur de ressource système devra pouvoir être isolé, voir même scalé sur plusieurs VM dédiées et ce sans mettre en péril l’architecture dont on va l’extraire (ni la refaire). J’irai jusqu’à dire qu’il faut que cela soit transparent. D’où la tolérance et l’adaptation.

    On est quand même bien loin d’un modèle REST classique, même, si je suis d’accord avec le fait que – l’héritage est bien visible – comme le précise Sergio Dos Santos.

  9. Publié par Ego, Il y a 2 années

    Toujours plein de blabla et on ne donne en réalité aucune définition. Comme tout ces trucs ‘Agiles’ on nous dit c’est bien c’est beau prenez en. Mais comme on dit n’importe quoi on ne sait en vérité pas donner de définition.
    Les micro-services une invention marketing de plus.
    Le vrai problème n’est pas abordé et on se bat toujours avec les 2 antagonistes que sont cohésion et faible couplage. Sachant que le truc réside dans le fonctionnel et dans. ….tout simplement des choix. Il n’y a pas de solution unique, un point c’est tout.

  10. Publié par Anas, Il y a 2 années

    Contrairement aux domaines du bâtiment ou de la mécanique où tous les concepts sont stables depuis longtemps, le domaine des systèmes informatiques est en phase d’émergence , il est normal que le vocabulaire se construise et se réadapte au fur et à mesure. Il est normal aussi qu’émergent des patterns d’architecture sujet à débats.
    Il n’y a certainement pas de solutions unique (d’ailleurs personne ne l’affirme), mais il y a des solution génériques (des patterns d’architecture) qui sont très important à identifier en phase de conception voir même en phase de cadrage (avant même la décision de lancer le projet de réalisation).

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *