web-dev-qa-db-fra.com

AWS lambda invoke n'appelant pas une autre fonction lambda - Node.js

Après avoir donné tous les droits pour invoquer la fonction. Ma fonction Lambda ne peut pas invoquer une autre fonction. Chaque fois que je reçois un délai d'expiration ayant 30 seconds timeout problème. Il semble que lambda ne puisse pas obtenir une autre fonction lambda

Mes lambdas sont dans la même région, la même politique, le même groupe de sécurité. Les VPC sont également les mêmes dans les deux lambdas. La seule chose est différente maintenant, c'est les fonctions lambda

Voici les droits de rôle

1) créé AWSLambdaExecute et AWSLambdaBasicExecutionRole

2) Création d'une fonction lambda à appeler Lambda_TEST

exports.handler = function(event, context) {
  console.log('Lambda TEST Received event:', JSON.stringify(event, null, 2));
  context.succeed(event);
};

3) Voici une autre fonction d'où elle est appelée.

var AWS = require('aws-sdk');
AWS.config.region = 'us-east-1';
var lambda = new AWS.Lambda();

exports.handler = function(event, context) {
 var params = {
   FunctionName: 'Lambda_TEST', // the lambda function we are going to invoke
   InvocationType: 'RequestResponse',
   LogType: 'Tail',
   Payload: '{ "name" : "Arpit" }'
 };

  lambda.invoke(params, function(err, data) {
   if (err) {
    context.fail(err);
   } else {
   context.succeed('Lambda_TEST said '+ data.Payload);
  }
 })
};

Référence tirée de: Ce lien

36
Arpit Vaishnav

Remarque

Je noterai exécuteur le lambda qui exécute le second lambda.


Pourquoi Timeout?

Puisque le exécuteur est "verrouillé" derrière un VPC - toutes les communications Internet sont bloquées.

Cela entraîne l'expiration de tous les appels http(s) car ils demandent que le paquet n'atteigne jamais la destination.

C'est pourquoi toutes les actions effectuées par aws-sdk entraîne un délai d'attente.


Solution simple

Si le exécuteur n'a pas pour être dans un VPC - il suffit de le retirer , un lambda peut également fonctionner sans VPC.

La localisation de lambda dans un VPC est requise lorsque le lambda appelle des ressources à l'intérieur du VPC.

Une vraie solution

D'après ce qui précède, il s'ensuit que toute ressource située à l'intérieur d'un VPC ne peut pas accéder à Internet - qui n'est pas correct - juste quelques configurations doivent être faites.

  1. Créez un VPC.
  2. Créez 2 Sous-réseaux, que l'un soit noté privé et le second public (ces termes sont expliqués à l'avance, continuez à lire ).
  3. Créez un Internet Gateway - il s'agit d'un routeur virtuel qui connecte un VPC à Internet.
  4. Créez un NAT Gateway - choisissez le sous-réseau public et créez un nouveau elastic IP pour cela (cette IP est locale à votre VPC) - ce composant dirigera les communications vers le internet-gateway.
  5. Créez 2 Tables de routage - une nommée publique et la seconde privée.

    1. Dans la table de routage public, accédez à Routes et ajoutez une nouvelle route:

    Destination: 0.0.0.0/0

    Cible: l'ID du internet-gateway

    1. Dans la table de routage privé, accédez à Routes et ajoutez une nouvelle route:

    Destination: 0.0.0.0/0

    Cible: l'ID du nat-gateway

    • Un sous-réseau privé est un sous-réseau qui dans sa table de routage - il n'y a aucune route vers un internet-gateway.

    • Un sous-réseau public est un sous-réseau qui dans sa table de routage - il existe une route vers un internet-gateway


Qu'est-ce que nous avions ici?

Nous avons créé quelque chose comme ça:

VPC with NAT and IGW

Ceci, ce qui permet aux ressources des sous-réseaux privés d'appeler Internet. Vous pouvez trouver plus de documentation ici .

62
johni

J'ai rencontré ce même problème lorsque des Lambdas qui sont "épinglées" sur un VPC ne peuvent pas invoquer d'autres Lambdas. J'ai traité ce problème, sans utiliser NAT, en refactorisant la structure de ma solution.

Disons que j'ai plusieurs lambdas, A, B, C, D, ... et je voudrais que ces Lambdas aient chacun un accès de requête à une base de données RDS. Afin d'avoir cet accès DB, j'ai besoin de mettre les lambdas dans le même VPC que la base de données. Mais j'aimerais aussi que plusieurs lambdas parmi A, B, C, D, ... s'invoquent mutuellement. Je rencontre donc le problème décrit par Arpit.

J'ai traité ce problème en divisant chaque Lambda en deux Lambdas: une qui se concentre sur le flux de processus (c'est-à-dire invoquer d'autres lambdas et être invoquée par un autre lambda); et l'autre se concentrant sur le travail "réel", comme l'interrogation de la base de données. J'ai donc maintenant les fonctions A_flow, B_flow, C_flow, D_flow, ...; et fonctions A_worker, B_worker, C_worker, D_worker, ... Les différents lambdas de flux ne sont pas "épinglés" à un VPC spécifique, et peuvent donc invoquer d'autres lambdas. Les divers Lambdas de travail sont dans le même VPC que la base de données et peuvent interroger la base de données.

Chaque flux lambda "délègue" le travail d'interaction avec DB au travailleur lambda correspondant. Il effectue cette délégation en effectuant un appel synchrone de l'ouvrier lambda. Les lambdas ouvriers n'invoquent aucun autre lambdas. (En termes de graphique de flux de processus, les lambdas de travail sont des nœuds terminaux.) Dans mon propre système, les invocations de Lambdas de flux par d'autres lambdas de flux ont généralement été asynchrones; mais je suppose qu'ils pourraient être synchrones si vous le souhaitez.

Même si j'ai conçu cette approche comme solution de contournement, elle présente une caractéristique intéressante de séparer proprement la conception des fonctions de haut niveau en (a) flux de processus et (b) en effectuant un travail plus détaillé, y compris l'interaction avec les ressources de base de données.

8
Jim Robertson