2017-07-21 3 views
4

Quand libérer des connexions et des ressources de nettoyage dans lambda. Dans l'application Node JS normale, nous utilisons le hookEvénement AWS Lambda Container destroy

process.on('exit', (code) => { 
    console.log(`About to exit with code: ${code}`); 
}); 

Cependant, cela ne fonctionne pas sur AWS Lambda. Résultant de la connexion Mysql en mode veille. Nous n'avons pas assez de ressources pour de telles connexions actives. Aucune documentation AWS ne spécifie un moyen d'y parvenir. Comment recevoir l'événement stop du conteneur AWS Lambda?

Répondre

5

EDIT: La réponse courte est qu'il n'y a pas un tel événement pour savoir quand le conteneur est arrêté. La réponse moyenne: après en avoir parlé avec quelqu'un chez AWS, je crois maintenant que vous devriez étendre les connexions de base de données au niveau du module afin qu'elles soient réutilisées tant que le conteneur existe. Lorsque votre conteneur est détruit, la connexion sera détruite à ce moment-là.

réponse originale:

Cette question touche à des questions assez complexes à prendre en compte avec des fonctions AWS Lambda, principalement en raison de la possibilité d'envisager la mise en commun de connexion ou les connexions longue durée de vie à votre base de données. Pour commencer, les fonctions Lambda Node.js exécutent en une seule, la fonction Node.js exportée avec cette signature (comme vous le savez sans doute):

exports.handler = (event, context, callback) => { 
    // TODO implement 
    callback(null, 'Hello from Lambda'); 
}; 

la plus propre et la plus simple pour gérer les connexions de base de données est de créer et détruisez-les avec chaque appel de fonction unique. Dans ce scénario, une connexion à la base de données serait créée au début de votre fonction et détruite avant l'appel de votre rappel final. Quelque chose comme ceci:

const mysql = require('mysql'); 

exports.handler = (event, context, callback) => { 
    let connection = mysql.createConnection({ 
    host  : 'localhost', 
    user  : 'me', 
    password : 'secret', 
    database : 'my_db' 
    }); 

    connection.connect(); 

    connection.query('SELECT 1 + 1 AS solution', (error, results, fields) => { 
    if (error) { 
     connection.end(); 
     callback(error); 
    } 
    else { 
     let retval = results[0].solution; 
     connection.end(); 
     console.log('The solution is: ', retval); 
     callback(null, retval); 
    } 
    }); 
}; 

NOTE: Je n'ai pas testé ce code. Je donne juste un exemple pour la discussion.

J'ai aussi vu des conversations like this one discuter de la possibilité de placer votre connexion à l'extérieur du corps principal de la fonction:

const mysql = require('mysql'); 

let connection = mysql.createConnection({ 
    host  : 'localhost', 
    user  : 'me', 
    password : 'secret', 
    database : 'my_db' 
}); 

connection.connect(); 

exports.handler = (event, context, callback) => { 
    // NOTE: should check if the connection is open first here 
    connection.query('SELECT 1 + 1 AS solution', (error, results, fields) => { 
    if (error) { 
     callback(error); 
    } 
    else { 
     let retval = results[0].solution; 
     console.log('The solution is: ', retval); 
     callback(null, retval); 
    } 
    }); 
}; 

La théorie est ici ceci: parce que AWS Lambda va essayer de réutiliser un conteneur existant après la première appel à votre fonction, l'appel de fonction suivant aura déjà une connexion à la base de données ouverte. L'exemple ci-dessus devrait probablement vérifier l'existence d'une connexion ouverte avant de l'utiliser, mais vous avez l'idée. Le problème est bien sûr que cela laisse votre connexion ouverte indéfiniment. Je ne suis pas un fan de cette approche, mais en fonction de vos circonstances spécifiques, cela pourrait fonctionner. Vous pouvez également introduire un pool de connexions dans ce scénario. Mais peu importe, vous n'avez aucun événement dans ce cas pour détruire proprement une connexion ou un pool. Le processus de conteneur hébergeant votre fonction serait lui-même tué. Donc, vous devrez compter sur votre base de données pour tuer la connexion de sa fin à un moment donné. Je peux me tromper sur certains de ces détails, mais je crois que c'est ce que vous cherchez à un niveau élevé. J'espère que cela pourra aider!

+0

J'utilise la deuxième approche. C'est pourquoi j'ai besoin de fermer la connexion. La première approche compromet la performance. Il établit une connexion à chaque demande qui est très coûteuse dans notre application. Y a-t-il un moyen de fermer la connexion avec la deuxième approche? –

+0

@ViswanathLekshmanan Je ne suis pas au courant de mécanismes qui vous permettraient de fermer et de détruire de manière fiable les connexions en dehors de l'exécution de la fonction elle-même. Nous ne nous connectons pas à notre base de données directement à partir de Lambda, mais hébergeons plutôt une API pour une utilisation interne sur ECS (conteneurs Docker) où nous avons un contrôle complet. –

+0

Merci pour l'info. –