web-dev-qa-db-fra.com

Communication de Microservices: éviter un point de défaillance unique

Autant que je sache, il existe deux modèles couramment utilisés lors de la gestion des services de communication dans une architecture de Microservices:

  1. Appel direct d'autres services. Par exemple: le service A gère certaines données, alors il doit indiquer au service B de faire quelque chose avec ces données. A sait B 'S URL du point d'extrémité et l'appelle directement.
  2. En utilisant un bus (généralement une file d'attente de message) pour envoyer des messages qui seront ramassés par les microservices simples. Par exemple: A enverra un message sur une file d'attente commune, B le recevra et saura quoi faire.

Les deux ont des descentes:

  • Les autres services d'appel direct mènent à des services de couplage serrés vers d'autres services. Si vous changez de service B, vous aurez probablement besoin d'adapter et de redéployer également tous les autres services qui interagissent avec B.
  • L'utilisation d'un bus est cool car vous n'avez pas besoin de savoir quel service sera en mesure de gérer la demande, mais si le MQ échoue à une raison quelconque, il deviendra le point unique de l'échec de l'ensemble du système.

Alors, quelle est la manière préférée de gérer les communications de services?

Avons-nous des alternatives qui peuvent réduire les défaillances et Éviter le couplage serré entre les microservices?

5
BackSlash

Comme vous le direz à juste titre, avoir un composant dédié à passer autour des messages est définitivement meilleur que de disposer de chaque service responsable de savoir comment accéder exactement à tous les services collaborateurs. Par conséquent, les files d'attente de messages, les bus de communication, etc. sont une bonne idée.

Et s'ils deviennent un seul point d'échec? Eh bien, vous faites ce que vous faites toujours pour la robustesse et la mise à l'échelle: vous déployez plusieurs instances de la file d'attente de messages. Si votre environnement ne peut pas continuer aucun d'entre eux, il est probable que vous n'obtiendrez pas de travail utile de toute façon. Problème résolu.

9
Kilian Foth

Eh bien, disons le service [~ # ~] B [~ # ~] échoue et n'est pas réactif. Maintenant, tout le processus ne peut pas continuer car cela dépend toujours de [~ # ~] B [~ # ~ ~] Pour faire sa part du travail. Comment est [~ # ~ # ~] B [~ # ~ ~] Pas un point unique d'échec alors?

L'avantage que je vois avec un bus commun (ou un orchestrateur ou tout ce que vous avez) est la possibilité de gérer des temps d'arrêt des services uniques, par ex. La file d'attente peut toujours garder les messages envoyés à [~ # ~ ~] b [~ # ~ ~] jusqu'à ce que le service soit sauvegardé et capable de les consommer.

De plus, les chances de maintenir un seul système hautement disponible sont mieux que de devoir s'inquiéter de N Systèmes différents avec différents propriétaires.

Voici un post intéressant de Martin Fowler qui fournit une solution aux microservices en utilisant des événements que je pense que vous pourriez utiliser.

2
jverce

Que ce soit la meilleure topologie ou l'autre dépend en grande partie de la forme de votre communication.

Par exemple, si vous envoyez principalement des messages autonomes qui ne nécessitent pas une conversation approfondie entre les services, un bus de messagerie courtimé fonctionne bien. Ceci est particulièrement vrai si les messages doivent atteindre plusieurs services ou que vous êtes agnostique, à quel service reprend le message. La résilience peut être gérée avec une configuration de courtier en cluster que la plupart des courtiers de messages populaires peuvent gérer.

Si vos communications sont surtout bidirives, cependant, les pairs à pair peuvent être la voie à suivre. Cela serait particulièrement vrai si vous diffusez des données entre les services. Il existe diverses techniques pour atténuer le couplage tel que l'utilisation d'un service de découverte pour identifier un partenaire approprié. Il existe également des techniques courantes pour limiter le couplage d'interface. Par exemple, avoir une API ressemblant à un repos et à l'aide d'une interface extensible, déclarative pour la communication d'entreprise. JSON est un format populaire, XML était avant cela etc.

Maintenant, cela ne veut pas dire que vous ne pouvez pas effectuer de pair-à-égal à travers un bus de message, mais vous finissez par gérer beaucoup d'état de session qui peut compliquer les choses. Si vos comms sont surtout un événement avec un peu de pair-pair, il peut toujours être préférable de le faire pour ne conserver qu'un seul système de messagerie.

De même, si vous diffusez principalement avec un peu de message qui passe, vous pouvez intégrer un protocole d'événement dans le protocole de diffusion en continu pour la même raison.

Et ce ne sont pas vos seules options. Pour des configurations complexes, j'aime bien utiliser Zeromq par laquelle j'utilise une communication "tissu" mais appliquer des topologies appropriées si nécessaire.

En résumé, la meilleure topologie de la messagerie dépend de la nature des messages. Il n'y a pas une réponse correcte mais, du côté positif, c'est un chemin bien troden. Vous devriez pouvoir obtenir de bonnes solutions avec des solutions sensibles, sauf si vous faites quelque chose de très inhabituel.

1
Alex