BLOG | NGINX

Création de microservices : Communication inter-processus dans une architecture de microservices

NGINX-Partie-de-F5-horiz-black-type-RGB
Miniature de Chris Richardson
Chris Richardson
Publié le 24 juillet 2015

Rédacteur – Cette série d’articles en sept parties est désormais terminée :

  1. Introduction aux microservices
  2. Création de microservices : Utilisation d'une passerelle API
  3. Création de microservices : Communication inter-processus dans une architecture de microservices (cet article)
  4. Découverte de services dans une architecture de microservices
  5. Gestion des données pilotée par les événements pour les microservices
  6. Choisir une stratégie de déploiement de microservices
  7. Refactorisation d'un monolithe en microservices

Vous pouvez également télécharger l'ensemble complet des articles, ainsi que des informations sur la mise en œuvre de microservices à l'aide de NGINX Plus, sous forme d'ebook – Microservices : De la conception au déploiement . Consultez également la nouvelle page Solutions Microservices .

Il s'agit du troisième article de notre série sur la création d'applications avec une architecture de microservices. Le premier article présente le modèle d’architecture de microservices , le compare au modèle d’architecture monolithique et discute des avantages et des inconvénients de l’utilisation de microservices. Le deuxième article décrit comment les clients d’une application communiquent avec les microservices via un intermédiaire appelé passerelle API . Dans cet article, nous examinons comment les services d’un système communiquent entre eux. Le quatrième article explore le problème étroitement lié de la découverte de services.

Introduction

Dans une application monolithique, les composants s’invoquent les uns les autres via des appels de méthodes ou de fonctions au niveau du langage. En revanche, une application basée sur des microservices est un système distribué exécuté sur plusieurs machines. Chaque instance de service est généralement un processus. Par conséquent, comme le montre le diagramme suivant, les services doivent interagir à l’aide d’un mécanisme de communication interprocessus (IPC).


Dans une application de microservices, les services ont besoin d'un mécanisme de communication interprocessus (IPC) (tandis que les modules d'un monolithe peuvent appeler des routines)

Nous examinerons plus tard des technologies IPC spécifiques, mais explorons d’abord divers problèmes de conception.

Styles d'interaction

Lors de la sélection d’un mécanisme IPC pour un service, il est utile de réfléchir d’abord à la manière dont les services interagissent. Il existe une variété de styles d’interaction client⇔service. Ils peuvent être classés selon deux dimensions. La première dimension est de savoir si l’interaction est de type un-à-un ou un-à-plusieurs :

  • Un à un – Chaque demande client est traitée par une seule instance de service.
  • Un à plusieurs – Chaque demande est traitée par plusieurs instances de service.

La deuxième dimension est de savoir si l’interaction est synchrone ou asynchrone :

  • Synchrone – Le client attend une réponse rapide du service et peut même se bloquer pendant qu'il attend.
  • Asynchrone – Le client ne se bloque pas en attendant une réponse, et la réponse, le cas échéant, n’est pas nécessairement envoyée immédiatement.

Le tableau suivant présente les différents styles d’interaction.

  Un à un Un-à-plusieurs
Synchrone Demande/réponse  — 
Asynchrone Notification Publier/s'abonner
Requête/réponse asynchrone Publier/réponses asynchrones

Il existe les types d’interactions individuelles suivants :

  • Demande/réponse – Un client fait une demande à un service et attend une réponse. Le client s’attend à ce que la réponse arrive en temps opportun. Dans une application basée sur des threads, le thread qui fait la demande peut même se bloquer pendant l’attente.
  • Notification (également appelée demande unidirectionnelle) – Un client envoie une demande à un service, mais aucune réponse n'est attendue ou envoyée.
  • Demande/réponse asynchrone – Un client envoie une demande à un service, qui répond de manière asynchrone. Le client ne se bloque pas pendant l’attente et est conçu avec l’hypothèse que la réponse pourrait ne pas arriver avant un certain temps.

Il existe les types d’interactions un-à-plusieurs suivants :

  • Publier/s'abonner – Un client publie un message de notification, qui est consommé par zéro ou plusieurs services intéressés.
  • Publication/réponses asynchrones – Un client publie un message de demande, puis attend un certain temps les réponses des services intéressés.

Chaque service utilise généralement une combinaison de ces styles d’interaction. Pour certains services, un seul mécanisme IPC est suffisant. D’autres services pourraient avoir besoin d’utiliser une combinaison de mécanismes IPC. Le diagramme suivant montre comment les services d'une application de commande de taxi peuvent interagir lorsque l'utilisateur demande un trajet.


Les services utilisent une combinaison de notifications, de demande/réponse et de publication/abonnement. Par exemple, le smartphone du passager envoie une notification au service de gestion de voyage pour demander une prise en charge. Le service de gestion de voyage vérifie que le compte du passager est actif en utilisant une requête/réponse pour invoquer le service passager. Le service de gestion de voyage crée ensuite le voyage et utilise la publication/abonnement pour notifier d'autres services, y compris le répartiteur, qui localise un chauffeur disponible.

Maintenant que nous avons examiné les styles d’interaction, voyons comment définir les API.

Définition des API

L'API d'un service est un contrat entre le service et ses clients. Quel que soit votre choix de mécanisme IPC, il est important de définir précisément l'API d'un service à l'aide d'une sorte de langage de définition d'interface (IDL). Il existe même de bons arguments en faveur de l’utilisation d’une approche API-first pour définir les services. Vous commencez le développement d’un service en écrivant la définition de l’interface et en la révisant avec les développeurs clients. Ce n’est qu’après avoir itéré sur la définition de l’API que vous implémentez le service. Réaliser cette conception en amont augmente vos chances de créer un service qui répond aux besoins de vos clients.

Comme vous le verrez plus loin dans cet article, la nature de la définition de l’API dépend du mécanisme IPC que vous utilisez. Si vous utilisez la messagerie, l'API se compose des canaux de messages et des types de messages. Si vous utilisez HTTP, l'API se compose des URL et des formats de demande et de réponse. Nous décrirons plus en détail certains IDL plus tard.

Évolution des API

L'API d'un service change invariablement au fil du temps. Dans une application monolithique, il est généralement simple de modifier l'API et de mettre à jour tous les appelants. Dans une application basée sur des microservices, c’est beaucoup plus difficile, même si tous les consommateurs de votre API sont d’autres services de la même application. En règle générale, vous ne pouvez pas forcer tous les clients à effectuer une mise à niveau en même temps que le service. De plus, vous déploierez probablement progressivement de nouvelles versions d’un service de sorte que les anciennes et les nouvelles versions d’un service s’exécuteront simultanément. Il est important d’avoir une stratégie pour faire face à ces problèmes.

La manière dont vous gérez un changement d’API dépend de la taille du changement. Certaines modifications sont mineures et rétrocompatibles avec la version précédente. Vous pouvez, par exemple, ajouter des attributs aux demandes ou aux réponses. Il est logique de concevoir les clients et les services de manière à ce qu’ils respectent le principe de robustesse . Les clients qui utilisent une ancienne API doivent continuer à travailler avec la nouvelle version du service. Le service fournit des valeurs par défaut pour les attributs de demande manquants et les clients ignorent tous les attributs de réponse supplémentaires. Il est important d'utiliser un mécanisme IPC et un format de messagerie qui vous permettent de faire évoluer facilement vos API.

Il arrive cependant que vous deviez apporter des modifications majeures et incompatibles à une API. Comme vous ne pouvez pas forcer les clients à effectuer une mise à niveau immédiate, un service doit prendre en charge les anciennes versions de l'API pendant un certain temps. Si vous utilisez un mécanisme basé sur HTTP tel que REST, une approche consiste à intégrer le numéro de version dans l’URL. Chaque instance de service peut gérer plusieurs versions simultanément. Vous pouvez également déployer différentes instances gérant chacune une version particulière.

Gestion des pannes partielles

Comme mentionné dans l’ article précédent sur l’API Gateway<.htmla>, dans un système distribué, le risque d’échec partiel est toujours présent. Étant donné que les clients et les services sont des processus distincts, il se peut qu’un service ne soit pas en mesure de répondre en temps opportun à la demande d’un client. Un service peut être hors service en raison d'une panne ou d'une maintenance. Ou bien le service peut être surchargé et répondre extrêmement lentement aux demandes.

Considérez, par exemple, le scénario Détails du produit de cet article. Imaginons que le service de recommandation ne réponde pas. Une implémentation naïve d’un client pourrait se bloquer indéfiniment en attendant une réponse. Non seulement cela entraînerait une mauvaise expérience utilisateur, mais dans de nombreuses applications, cela consommerait une ressource précieuse telle qu'un thread. Finalement, le runtime manque de threads et cesse de répondre, comme le montre la figure suivante.


Une application de microservices doit être conçue pour gérer les échecs partiels, sinon le runtime risque de manquer de threads lorsque les clients se bloquent en attendant un service qui ne répond pas

Pour éviter ce problème, il est essentiel de concevoir vos services pour gérer les pannes partielles.

Une bonne approche à suivre est celle décrite par Netflix . Les stratégies pour faire face aux défaillances partielles comprennent :

  • Délais d’attente du réseau – Ne bloquez jamais indéfiniment et utilisez toujours des délais d’attente lorsque vous attendez une réponse. L’utilisation de délais d’attente garantit que les ressources ne sont jamais immobilisées indéfiniment.
  • Limitation du nombre de demandes en attente – Imposer une limite supérieure au nombre de demandes en attente qu'un client peut avoir avec un service particulier. Si la limite a été atteinte, il est probablement inutile de faire des demandes supplémentaires et ces tentatives doivent échouer immédiatement.
  • Modèle de disjoncteur – Suivez le nombre de demandes réussies et échouées. Si le taux d'erreur dépasse un seuil configuré, déclenchez le disjoncteur afin que les tentatives ultérieures échouent immédiatement. Si un grand nombre de requêtes échouent, cela suggère que le service n'est pas disponible et que l'envoi de requêtes est inutile. Après un délai d'attente, le client doit réessayer et, en cas de succès, fermer le disjoncteur.
  • Fournir des solutions de secours – Exécuter une logique de secours lorsqu’une demande échoue. Par exemple, renvoyez des données mises en cache ou une valeur par défaut telle qu'un ensemble vide de recommandations.

Netflix Hystrix est une bibliothèque open source qui implémente ces modèles et d'autres. Si vous utilisez la JVM, vous devriez certainement envisager d'utiliser Hystrix. Et si vous travaillez dans un environnement non JVM, vous devez utiliser une bibliothèque équivalente.

Technologies IPC

Il existe de nombreuses technologies IPC différentes parmi lesquelles choisir. Les services peuvent utiliser des mécanismes de communication synchrones basés sur des requêtes/réponses tels que REST basé sur HTTP ou Thrift. Alternativement, ils peuvent utiliser des mécanismes de communication asynchrones basés sur des messages tels que AMQP ou STOMP. Il existe également une variété de formats de messages différents. Les services peuvent utiliser des formats textuels lisibles par l’homme tels que JSON ou XML. Alternativement, ils peuvent utiliser un format binaire (qui est plus efficace) tel qu'Avro ou Protocol Buffers. Nous examinerons plus tard les mécanismes IPC synchrones, mais discutons d’abord des mécanismes IPC asynchrones.

Communication asynchrone basée sur des messages

Lors de l'utilisation de la messagerie, les processus communiquent en échangeant des messages de manière asynchrone. Un client fait une demande à un service en lui envoyant un message. Si le service doit répondre, il le fait en renvoyant un message séparé au client. Comme la communication est asynchrone, le client ne se bloque pas en attendant une réponse. Au lieu de cela, le client est informé que la réponse ne sera pas reçue immédiatement.

Un message se compose d'en-têtes (métadonnées telles que l'expéditeur) et d'un corps de message. Les messages sont échangés via des canaux . N'importe quel nombre de producteurs peut envoyer des messages à un canal. De même, n’importe quel nombre de consommateurs peut recevoir des messages d’un canal. Il existe deux types de canaux : point à point et publication-abonnement . Un canal point à point délivre un message à exactement l’un des consommateurs qui lit le canal. Les services utilisent des canaux point à point pour les styles d’interaction un à un décrits précédemment. Un canal de publication-abonnement délivre chaque message à tous les consommateurs attachés. Les services utilisent des canaux de publication-abonnement pour les styles d’interaction un-à-plusieurs décrits ci-dessus.

Le diagramme suivant montre comment l’application de réservation de taxi peut utiliser les canaux de publication-abonnement.


Les microservices dans les applications de réservation de taxi utilisent des canaux de publication-abonnement pour la communication entre le répartiteur et les autres services

Le service de gestion de voyage informe les services intéressés, tels que le répartiteur, d'un nouveau voyage en écrivant un message de voyage créé sur un canal de publication-abonnement. Le répartiteur trouve un pilote disponible et avertit les autres services en écrivant un message de proposition de pilote sur un canal de publication-abonnement.

Il existe de nombreux systèmes de messagerie parmi lesquels choisir. Vous devez en choisir un qui prend en charge une variété de langages de programmation. Certains systèmes de messagerie prennent en charge des protocoles standards tels que AMQP et STOMP. D’autres systèmes de messagerie ont des protocoles propriétaires mais documentés. Il existe un grand nombre de systèmes de messagerie open source parmi lesquels choisir, notamment RabbitMQ , Apache Kafka , Apache ActiveMQ et NSQ . À un niveau élevé, ils prennent tous en charge une certaine forme de messages et de canaux. Ils s’efforcent tous d’être fiables, performants et évolutifs. Il existe cependant des différences significatives dans les détails du modèle de messagerie de chaque courtier.

L’utilisation de la messagerie présente de nombreux avantages :

  • Découple le client du service – Un client fait une demande simplement en envoyant un message au canal approprié. Le client n’a aucune connaissance des instances de service. Il n’est pas nécessaire d’utiliser un mécanisme de découverte pour déterminer l’emplacement d’une instance de service.
  • Mise en mémoire tampon des messages – Avec un protocole de demande/réponse synchrone, tel que HTTP, le client et le service doivent être disponibles pendant toute la durée de l'échange. En revanche, un courtier de messages met en file d'attente les messages écrits sur un canal jusqu'à ce qu'ils puissent être traités par le consommateur. Cela signifie, par exemple, qu’une boutique en ligne peut accepter les commandes des clients même lorsque le système de traitement des commandes est lent ou indisponible. Les messages de commande sont simplement mis en file d'attente.
  • Interactions client-service flexibles – La messagerie prend en charge tous les styles d’interaction décrits précédemment.
  • Communication interprocessus explicite – Les mécanismes basés sur RPC tentent de faire en sorte que l’appel d’un service distant ressemble à l’appel d’un service local. Cependant, en raison des lois de la physique et de la possibilité d’une défaillance partielle, ils sont en fait assez différents. La messagerie rend ces différences très explicites afin que les développeurs ne soient pas bercés par un faux sentiment de sécurité.

L’utilisation de la messagerie présente cependant certains inconvénients :

  • Complexité opérationnelle supplémentaire – Le système de messagerie est un autre composant du système qui doit être installé, configuré et exploité. Il est essentiel que le courtier de messages soit hautement disponible, sinon la fiabilité du système est affectée.
  • Complexité de la mise en œuvre de l’interaction basée sur une demande/réponse – L’interaction de type demande/réponse nécessite un certain travail de mise en œuvre. Chaque message de demande doit contenir un identifiant de canal de réponse et un identifiant de corrélation. Le service écrit un message de réponse contenant l’ID de corrélation sur le canal de réponse. Le client utilise l’ID de corrélation pour faire correspondre la réponse à la demande. Il est souvent plus facile d’utiliser un mécanisme IPC qui prend directement en charge la requête/réponse.

Maintenant que nous avons vu l’utilisation de l’IPC basé sur la messagerie, examinons l’IPC basé sur les requêtes/réponses.

Synchrone, requête/réponse IPC

Lors de l'utilisation d'un mécanisme IPC synchrone basé sur une demande/réponse, un client envoie une demande à un service. Le service traite la demande et renvoie une réponse. Dans de nombreux clients, le thread qui effectue la requête se bloque en attendant une réponse. D’autres clients peuvent utiliser du code client asynchrone, piloté par événements, qui est peut-être encapsulé par Futures ou Rx Observables. Cependant, contrairement à l’utilisation de la messagerie, le client suppose que la réponse arrivera en temps opportun. Il existe de nombreux protocoles parmi lesquels choisir. REST et Thrift sont deux protocoles populaires. Commençons d’abord par examiner REST.

REPOS

Aujourd’hui, il est à la mode de développer des API dans le style RESTful . REST est un mécanisme IPC qui utilise (presque toujours) HTTP. Un concept clé dans REST est une ressource, qui représente généralement un objet métier tel qu'un client ou un produit, ou une collection d'objets métier. REST utilise les verbes HTTP pour manipuler les ressources, qui sont référencées à l'aide d'une URL. Par exemple, une requête GET renvoie la représentation d'une ressource, qui peut se présenter sous la forme d'un document XML ou d'un objet JSON. Une requête POST crée une nouvelle ressource et une requête PUT met à jour une ressource. Pour citer Roy Fielding, le créateur de REST :

« REST fournit un ensemble de contraintes architecturales qui, lorsqu'elles sont appliquées dans leur ensemble, mettent l'accent sur l'évolutivité des interactions des composants, la généralité des interfaces, le déploiement indépendant des composants et des composants intermédiaires pour réduire la latence des interactions, renforcer la sécurité et encapsuler les systèmes existants. »

Le diagramme suivant montre l’une des façons dont l’application de commande de taxi peut utiliser REST.


Dans une application de réservation de taxi basée sur des microservices, le smartphone du passager envoie une requête POST, que le microservice de gestion de voyage convertit en requête GET au microservice de vérification des passagers

Le smartphone du passager demande un voyage en effectuant une requête POST à la ressource /trips du service Trip Management. Ce service gère la demande en envoyant une requête GET pour obtenir des informations sur le passager au service de gestion des passagers. Après avoir vérifié que le passager est autorisé à créer un voyage, le service de gestion de voyage crée le voyage et renvoie un201 réponse au smartphone.

De nombreux développeurs affirment que leurs API basées sur HTTP sont RESTful. Cependant, comme le décrit Fielding dans cet article de blog , ce n’est pas le cas de tous. Leonard Richardson (sans lien de parenté) définit un modèle de maturité très utile pour REST qui se compose des niveaux suivants.

  • Niveau 0 – Les clients d’une API de niveau 0 invoquent le service en effectuant des requêtes HTTP POST vers son seul point de terminaison URL. Chaque requête spécifie l'action à effectuer, la cible de l'action (par exemple l'objet métier) et les éventuels paramètres.
  • Niveau 1 – Une API de niveau 1 prend en charge l’idée de ressources. Pour effectuer une action sur une ressource, un client effectue une requête POST qui spécifie l'action à effectuer et tous les paramètres.
  • Niveau 2 – Une API de niveau 2 utilise des verbes HTTP pour effectuer des actions : GET pour récupérer, POST pour créer et PUT pour mettre à jour. Les paramètres et le corps de la requête, le cas échéant, spécifient les paramètres de l'action. Cela permet aux services d'exploiter l'infrastructure Web telle que la mise en cache des requêtes GET .
  • Niveau 3 – La conception d’une API de niveau 3 est basée sur le principe terriblement nommé HATEOAS (Hypertext As The Engine Of Application State). L’idée de base est que la représentation d’une ressource renvoyée par une requête GET contient des liens permettant d’effectuer les actions autorisées sur cette ressource. Par exemple, un client peut annuler une commande en utilisant un lien dans la représentation de commande renvoyée en réponse à la requête GET envoyée pour récupérer la commande. Les avantages de HATEOAS incluent le fait de ne plus avoir à intégrer les URL dans le code client. Un autre avantage est que, comme la représentation d’une ressource contient des liens vers les actions autorisées, le client n’a pas à deviner quelles actions peuvent être effectuées sur une ressource dans son état actuel.

L’utilisation d’un protocole basé sur HTTP présente de nombreux avantages :

  • HTTP est simple et familier.
  • Vous pouvez tester une API HTTP depuis un navigateur à l'aide d'une extension telle que Postman ou depuis la ligne de commande à l'aide de curl (en supposant que JSON ou un autre format de texte soit utilisé).
  • Il prend directement en charge la communication de type demande/réponse.
  • HTTP est, bien entendu, compatible avec les pare-feu.
  • Il ne nécessite pas de courtier intermédiaire, ce qui simplifie l’architecture du système.

L'utilisation de HTTP présente certains inconvénients :

  • Il prend uniquement en charge directement le style d’interaction demande/réponse. Vous pouvez utiliser HTTP pour les notifications, mais le serveur doit toujours envoyer une réponse HTTP.
  • Étant donné que le client et le service communiquent directement (sans intermédiaire pour mettre en mémoire tampon les messages), ils doivent tous deux être en cours d'exécution pendant toute la durée de l'échange.
  • Le client doit connaître l’emplacement (c’est-à-dire l’URL) de chaque instance de service. Comme décrit dans l’ article précédent sur la passerelle API , il s’agit d’un problème non trivial dans une application moderne. Les clients doivent utiliser un mécanisme de découverte de service pour localiser les instances de service.

La communauté des développeurs a récemment redécouvert la valeur d’un langage de définition d’interface pour les API RESTful. Il existe quelques options, notamment RAML et Swagger . Certains IDL tels que Swagger vous permettent de définir le format des messages de demande et de réponse. D'autres, comme RAML, nécessitent l'utilisation d'une spécification distincte telle que JSON Schema . En plus de décrire les API, les IDL disposent généralement d'outils qui génèrent des stubs clients et des squelettes de serveurs à partir d'une définition d'interface.

Épargne

Apache Thrift est une alternative intéressante à REST. Il s'agit d'un framework permettant d'écrire des clients et des serveurs RPC multilingues. Thrift fournit un IDL de style C pour définir vos API. Vous utilisez le compilateur Thrift pour générer des stubs côté client et des squelettes côté serveur. Le compilateur génère du code pour une variété de langages, notamment C++, Java, Python, PHP, Ruby, Erlang et Node.js.

Une interface Thrift se compose d'un ou plusieurs services. Une définition de service est analogue à une interface Java. Il s'agit d'un ensemble de méthodes fortement typées. Les méthodes d’épargne peuvent soit renvoyer une valeur (éventuellement nulle), soit être définies comme unidirectionnelles. Les méthodes qui renvoient une valeur implémentent le style d’interaction demande/réponse. Le client attend une réponse et peut générer une exception. Les méthodes unidirectionnelles correspondent au style de notification de l’interaction. Le serveur n'envoie pas de réponse.

Thrift prend en charge différents formats de messages : JSON, binaire et binaire compact. Le binaire est plus efficace que JSON car il est plus rapide à décoder. Et, comme son nom l’indique, le binaire compact est un format peu encombrant. JSON est, bien entendu, convivial pour les humains et les navigateurs. Thrift vous offre également un choix de protocoles de transport, notamment TCP brut et HTTP. Le TCP brut est probablement plus efficace que HTTP. Cependant, HTTP est compatible avec le pare-feu, le navigateur et l'utilisateur.

Formats des messages

Maintenant que nous avons examiné HTTP et Thrift, examinons la question des formats de message. Si vous utilisez un système de messagerie ou REST, vous pouvez choisir le format de votre message. D'autres mécanismes IPC tels que Thrift peuvent ne prendre en charge qu'un petit nombre de formats de messages, peut-être un seul. Dans les deux cas, il est important d’utiliser un format de message multilingue. Même si vous écrivez vos microservices dans un seul langage aujourd’hui, il est probable que vous utiliserez d’autres langages à l’avenir.

Il existe deux principaux types de formats de messages : texte et binaire. Les exemples de formats basés sur du texte incluent JSON et XML. L’un des avantages de ces formats est qu’ils sont non seulement lisibles par l’homme, mais qu’ils sont également autodescriptifs. Dans JSON, les attributs d’un objet sont représentés par une collection de paires nom-valeur. De même, dans XML, les attributs sont représentés par des éléments nommés et des valeurs. Cela permet au consommateur d’un message de sélectionner les valeurs qui l’intéressent et d’ignorer le reste. Par conséquent, des modifications mineures apportées au format du message peuvent être facilement rétrocompatibles.

La structure des documents XML est spécifiée par un schéma XML . Au fil du temps, la communauté des développeurs s’est rendu compte que JSON avait également besoin d’un mécanisme similaire. Une option consiste à utiliser le schéma JSON , soit de manière autonome, soit dans le cadre d’un IDL tel que Swagger.

L’inconvénient de l’utilisation d’un format de message basé sur du texte est que les messages ont tendance à être verbeux, en particulier XML. Étant donné que les messages sont autodescriptifs, chaque message contient le nom des attributs en plus de leurs valeurs. Un autre inconvénient est la surcharge liée à l’analyse du texte. Par conséquent, vous pourriez envisager d’utiliser un format binaire.

Il existe plusieurs formats binaires parmi lesquels choisir. Si vous utilisez Thrift RPC, vous pouvez utiliser Thrift binaire. Si vous devez choisir le format du message, les options les plus populaires incluent Protocol Buffers et Apache Avro . Ces deux formats fournissent un IDL typé pour définir la structure de vos messages. Une différence cependant est que les tampons de protocole utilisent des champs balisés, alors qu'un consommateur Avro doit connaître le schéma pour interpréter les messages. Par conséquent, l’évolution des API est plus facile avec Protocol Buffers qu’avec Avro. Cet article de blog est une excellente comparaison de Thrift, Protocol Buffers et Avro.

Résumé

Les microservices doivent communiquer à l’aide d’un mécanisme de communication interprocessus. Lors de la conception de la manière dont vos services communiqueront, vous devez prendre en compte divers problèmes : comment les services interagissent, comment spécifier l'API pour chaque service, comment faire évoluer les API et comment gérer les échecs partiels. Il existe deux types de mécanismes IPC que les microservices peuvent utiliser : la messagerie asynchrone et la requête/réponse synchrone. Dans le prochain article de la série, nous examinerons le problème de la découverte de services dans une architecture de microservices.

Rédacteur – Cette série d’articles en sept parties est désormais terminée :

  1. Introduction aux microservices
  2. Création de microservices : Utilisation d'une passerelle API
  3. Création de microservices : Communication inter-processus dans une architecture de microservices (cet article)
  4. Découverte de services dans une architecture de microservices
  5. Gestion des données pilotée par les événements pour les microservices
  6. Choisir une stratégie de déploiement de microservices
  7. Refactorisation d'un monolithe en microservices

Vous pouvez également télécharger l'ensemble complet des articles, ainsi que des informations sur la mise en œuvre de microservices à l'aide de NGINX Plus, sous forme d'ebook – Microservices : De la conception au déploiement .

Le blogueur invité Chris Richardson est le fondateur du CloudFoundry.com original, un PaaS (Platform as a Service) Java précoce pour Amazon EC2. Il conseille désormais les organisations pour améliorer la manière dont elles développent et déploient des applications. Il blogue également régulièrement sur les microservices sur http://microservices.io .


« Cet article de blog peut faire référence à des produits qui ne sont plus disponibles et/ou qui ne sont plus pris en charge. Pour obtenir les informations les plus récentes sur les produits et solutions F5 NGINX disponibles, explorez notre famille de produits NGINX . NGINX fait désormais partie de F5. Tous les liens NGINX.com précédents redirigeront vers un contenu NGINX similaire sur F5.com."