web-dev-qa-db-fra.com

Commentaires les microservices acquis avec AWS API Gateway + Lambda/ECS pourraient-ils parler?

Je développe actuellement une application "micro-services" utilisant AWS API Gateway avec Lambda ou ECS pour le calcul. Le problème est maintenant que la communication entre les services se fait via des appels API via la passerelle API. Cela semble inefficace et moins sécurisé que possible. Existe-t-il un moyen de faire en sorte que mes microservices se parlent de manière plus performante et sécurisée? Vous aimez parler directement au sein du réseau privé?

Une façon dont j'ai pensé est plusieurs niveaux de passerelle API.

  • 1 passerelle API publique
  • 1 passerelle API privée par microservice. Et chaque microservice peut appeler un autre microservice "directement" dans le réseau privé.

Mais de cette manière, je dois "dupliquer" mes routes dans 2 niveaux d'API ... cela ne semble pas idéal. Je pensais peut-être utiliser {proxy+}. Donc, tout ce que /payment/{proxy+} va à la passerelle API de paiement et ainsi de suite - il reste encore 2 niveaux de passerelle API ... mais cela semble être le meilleur que je puisse faire?

Peut-être qu'il y a un meilleur moyen?

7
Jiew Meng

Il y aura plusieurs façons de créer des micro-services. Je commencerai par vous familiariser avec le livre blanc publié par AWS: Microservices on AWS , Livre blanc - PDF version .

Dans votre question, vous avez déclaré: "Le problème est maintenant que la communication entre les services se fait via des appels d'API via la passerelle API. Cela semble inefficace et moins sécurisé qu'il ne peut l'être. Existe-t-il un moyen de faire parler mes microservices dans une manière plus performante et sécurisée? "

Oui - En fait, le livre blanc AWS et API Gateway FAQ font référence à la passerelle API en tant que "porte d'entrée" de votre application. L'intention de API Gateway doit être utilisée pour les services externes qui communiquent avec vos services AWS. Ne sont pas des services AWS communiquant entre eux.

Les ressources AWS peuvent communiquer entre elles pour appeler des micro-services de plusieurs manières. Quelques-uns sont décrits dans le livre blanc et voici une autre ressource que j'ai utilisée: Better Together: Amazon ECS et AWS Lambda . Les services que vous utilisez seront basés sur vos besoins.

En décomposant les applications monolithiques en petits microservices, la charge de communication augmente, car les microservices doivent se parler. Dans de nombreuses implémentations, REST sur HTTP est utilisé comme protocole de communication. C'est un protocole léger, mais des volumes élevés peuvent causer des problèmes. Dans certains cas, il peut être judicieux de penser à la consolidation de services qui envoient beaucoup de messages dans les deux sens. Si vous vous retrouvez dans une situation où vous consolidez de plus en plus vos services simplement pour réduire le nombre de discussions, vous devriez passer en revue vos domaines problématiques et votre modèle de domaine.

À ma connaissance, la racine de votre problème est l’acheminement des demandes vers des micro-services. Pour conserver les " Caractéristiques de Microservices ", vous devez choisir une solution unique pour gérer le routage.

Passerelle API

Vous avez mentionné l'utilisation d'API Gateway en tant que solution de routage. API Gateway peut être utilisé pour le routage ... Toutefois, si vous choisissez d'utiliser API Gateway pour le routage, vous devez définir vos itinéraires de manière explicite sur un niveau. Pourquoi?

  1. L'utilisation de {proxy +} augmente la surface d'attaque car le routage doit être correctement géré dans un autre micro-service.
  2. L'un des avantages de la définition des itinéraires dans API Gateway est que votre API est auto-documentée. Si vous avez plusieurs passerelles d'API, cela deviendra complice.

L'inconvénient est que cela prendra du temps et que vous devrez peut-être modifier les API existantes qui ont déjà été définies. Cependant, vous apportez peut-être déjà des modifications à la base de codes existante pour suivre les meilleures pratiques en matière de micro-services.

Lambda ou autre ressource de calcul

Malgré les raisons énumérées ci-dessus pour utiliser API Gateway pour le routage, si elle est configurée correctement, une autre ressource peut gérer correctement le routage. Vous pouvez attribuer un proxy API Gateway à une fonction Lambda qui définit tous les itinéraires de micro-service ou une autre ressource de votre VPC avec des itinéraires définis.

Résultat

Ce que vous faites dépend de vos besoins et de votre temps. Si vous avez déjà une API définie quelque part et souhaitez simplement utiliser API Gateway pour contrôler, surveiller, sécuriser et consigner les demandes, vous utiliserez alors API Gateway comme proxy. Si vous souhaitez tirer pleinement parti d'API Gateway, définissez explicitement chaque route à l'intérieur de celle-ci. Les deux approches peuvent suivre les meilleures pratiques en matière de micro-services. Toutefois, il est de mon opinion que la définition de chaque API publique dans API Gateway constitue le meilleur moyen de s’aligner sur l’architecture de micro-service. Les autres réponses font également un excellent travail en expliquant les compromis entre chaque approche.

3
KiteCoder

Je vais à supposons Lambdas pour la solution mais ils pourraient tout aussi bien être des instances ECS ou des ELB.

Problème actuel  original problem

Un concept important à comprendre à propos de lambdas avant de vous lancer dans la solution est le découplage de votre code de l'application et d'un event_source.

Une source d'événements est une manière différente d'appeler votre code d'application} _. Vous avez mentionné API Gateway, qui n’est qu’une des méthodes permettant d’appeler votre lambda (une requête HTTP). Les autres event sources intéressants pour votre solution sont:

  • Passerelle Api (comme indiqué, non efficace pour la communication entre services)
  • Invocation directe (via AWS Sdk, peut être synchronisé ou async)
  • SNS (pub/sub, eventbus)
  • Il existe plus de 20 façons différentes d'invoquer un lambda. Documentation

Cas d'utilisation n ° 1 Sync

Donc, si votre HTTP_RESPONSE dépend d'un lambda en appelant un autre et de ce 2ème résultat lambdas. Un appel direct invoke pourrait être une solution assez efficace, de cette manière, vous pourrez invoke le lambda de manière synchrone. Cela signifie également que lambda doit être abonné à une passerelle API en tant que source d'événements et disposer d'un code permettant de normaliser les 2 types d'événements. (C’est pourquoi la documentation lambda a généralement event parmi les paramètres)

 Sync use case

Cas d'utilisation n ° 2 asynchrone

Si votre réponse HTTP ne dépend pas de l'exécution des autres micro services (lambdas). Je recommande fortement SNS pour ce cas d'utilisation, car votre lambda d'origine publie un seul événement et vous pouvez avoir plus d'un lambda abonné à cet événement exécuté en parallèle.

 Async/parallel execution

Cas d'utilisation plus compliqués

Pour les cas d'utilisation plus compliqués:

4
Dudemullet

Il existe plusieurs façons et approches pour ce faire, en plus d'être lié à votre configuration et infrastructure actuelles sans exclure la flexibilité d'implémentation/modification de la base de code existante.

Lorsque vous essayez de communiquer entre des services situés derrière la passerelle API, vous devez les implémenter avec soin pour éviter les boucles, exposer vos données ou, pire encore, vous bloquer, voir l'image "générique" pour mieux comprendre:  enter image description here

Lors de l’utilisation deHTTPpour la communication entre les services, il est souvent courant de voir le trafic sortir de l’infrastructure actuelle, puis revenir par la même passerelle d’API, ce qui pourrait être évité en passant directement à l’autre service. en place à la place.

Dans l'image précédente, par exemple, lorsque service B a besoin de communiquer avec service A, il est conseillé de le faire via le point de terminaison interne (ELB) au lieu de sortir et de revenir en arrière via la passerelle d'API.

Une autre approche consiste à utiliser "uniquement"HTTPdans la passerelle API et à utiliser d'autres protocoles pour communiquer au sein de vos services, par exemple, gRPC . (Ce n'est pas la meilleure alternative dans certains cas car cela dépend de votre architecture et de votre flexibilité pour modifier/adapter le code existant)

Dans certains cas, votre infrastructure est plus complexe et vous ne pouvez pas communiquer à la demande dans vos conteneurs ou les noeuds finaux sont tout simplement inaccessibles. Dans ce cas, vous pouvez essayer de mettre en œuvre une architecture pilotée par les événements (SQS et AWS Lambda )

J'aime aller asynchrone en utilisant des événements/files d'attente lorsque cela est possible, de mon point de vue "évolue" mieux et que les services doivent devenir uniquement des consommateurs/travailleurs, outre le besoin d'écouter les demandes entrantes (pas de HTTP nécessaire), ici est un article expliquant comment utiliser lapin dans ce but microservices communicants au sein de docker

Ce ne sont là que quelques idées qui, espérons-le, pourraient vous aider à trouver votre propre "meilleur" moyen, car quelque chose varie beaucoup et chaque scénario est unique.

1
nbari

Je ne pense pas que votre question concerne strictement AWS, mais plutôt un moyen général de communication entre les services.

API Gateway est utilisé en tant que service Edge, qui est un service situé à la limite de votre infrastructure principale et accessible aux parties externes. Pour la communication derrière la passerelle API, entre vos microservices, il n'est pas nécessaire de repasser par la passerelle API.

Il y a 2 moyens de communication que je mentionnerais pour votre cas:

  • HTTP
  • Messagerie

HTTP est le moyen de communication le plus simpliste, car il est naturellement plus facile à comprendre et il existe une multitude de bibliothèques qui le rendent facile à utiliser.

Malgré les avantages, il y a plusieurs choses à surveiller.

  • Gestion des échecs
  • Coupure de circuit en cas d'indisponibilité d'un service
  • Cohérence
  • Nouvelles tentatives
  • Utilisation de la découverte de service (par exemple, Eureka) pour rendre le système plus flexible lors de l'appel d'un autre service

Du côté de la messagerie, vous devez traiter avec le traitement asynchrone, des problèmes d’infrastructure tels que la configuration et la maintenance du courtier de messages, ce n’est pas aussi facile à utiliser que le HTTP pur, mais vous pouvez résoudre les problèmes de cohérence simplement en fin de compte.

Globalement, vous devez prendre en compte des tonnes de choses et tout est une question de compromis. Si vous ne faites que commencer avec les microservices, je pense qu'il est préférable de commencer par utiliser HTTP pour la communication, puis de passer lentement à la solution de messagerie.

Par exemple, dans le monde Java + Spring Cloud Netflix, vous pouvez utiliser Eureka avec Feign. Grâce à cela, il est très facile d'utiliser une adresse logique pour les services, ce qui permet à Eureka de traduire les adresses IP et les ports réels. De même, si vous voulez utiliser Swagger pour vos API REST, vous pouvez même générer des stubs de clients Feign à partir de ceux-ci.

1
galovics

Cela fait un moment que je me pose la même question et je ne trouve toujours pas de bonne solution générique ... Pour ce que ça vaut ...

Si la communication est à sens unique et que "l'appelant" n'a pas besoin d'attendre un résultat, je trouve les flux Kinesis très puissants - postez simplement une "tâche" sur le flux et laissez le flux déclencher un lambda pour le traiter. Mais évidemment, cela fonctionne dans des cas très limités ...

Pour le monde réponse-réponse, j'appelle les points finaux API Gateway comme le ferait un utilisateur final (avec l'ajout des frais généraux de marshaling et de dissémination des données pour s'adapter au monde HTTP et des authentifications multiples inutiles).

Dans de rares cas, une seule fonction lambda dorsale peut être invoquée directement par lambda de l’API de la passerelle et par d’autres microservices. Cela ajoute un "saut" supplémentaire pour les "utilisateurs finaux" (au lieu de [UI -> API de passerelle -> GatewayAPI lambda], maintenant j'ai [UI -> API de passerelle -> GatewayAPI lambda -> Backend lambda]), mais rend microservice appels initiés plus rapidement (car l'appel et toutes les données associées n'ont plus besoin d'être "tunnelés" via une requête HTTP). De plus, cela rend l’architecture plus compliquée (je n’ai plus une API officielle, mais maintenant une dépendance directe du "canal arrière").

0
xpa1492