Serverless: Lokal ausgeführte Funktion hängt (bei Verwendung des MySQL-Verbindungspools)

Erstellt am 8. Jan. 2016  ·  3Kommentare  ·  Quelle: serverless/serverless

Ich bin neu bei Serverless (JAWS), daher könnte ich hier etwas Offensichtliches übersehen. Ich habe eine sehr einfache Testfunktion, die das Knotenmodul mysql verwendet, einen Verbindungspool instanziiert, eine Verbindung erhält und sie dann wieder freigibt:

var mysql = require ("mysql");
var config = {
    // settings go here
};

module.exports.respond = function(event, cb) {

    var pool = mysql.createPool({
        connectionLimit: config.connectionLimit,
        host: config.host,
        user: config.user,
        password: config.password,
        multipleStatements: true
    });

    pool.getConnection(function(err, connection) {
        err && console.log("Error establishing a database connection: ", err);
        connection.release();

        return cb(err, "Done.");
    });

};

Diese Funktion funktioniert einwandfrei, wenn sie auf AWS bereitgestellt wird, sie wird innerhalb weniger Millisekunden beendet und die Welt ist hell und schön. Wenn Sie diese Funktion jedoch lokal mit serverless function run , wird am Ende " Done. " ausgegeben, aber nie beendet.

Ich habe herausgefunden, dass der Grund wahrscheinlich darin besteht, dass ich den MySQL-Verbindungspool nicht freigebe. Wenn ich den letzten Befehl in der obigen Funktion wie folgt ändere, dann funktioniert alles:

        pool.end(function() {
            return cb(err, "Done.");
        });

Es _scheint_, dass Serverless auf das Ende der mysql-Ereignisschleife wartet und nicht beendet wird, wenn dies nicht geschieht. Nach meinem Verständnis sollte ich jedoch den Verbindungspool _nicht_ schließen, damit zukünftige Aufrufe derselben Lambda-Funktion den Pool wiederverwenden können und somit keine neue DB-Verbindung erforderlich ist, sondern eine vorhandene wiederverwendet wird.

Wird das Verhalten von Serverless hier also blockiert oder handelt es sich um einen Fehler? Ich hatte den Eindruck, dass das Aufrufen context.done() beendet und zurückgegeben werden würde. Ich würde also erwarten, dass Serverless beendet wird, wenn dies lokal getestet wird.

Hilfreichster Kommentar

Für alle, die dieses Problem immer noch haben ... Ich denke, es ist fraglich, ob dies ein Fehler ist oder nicht. Der Grund, warum sls nicht heruntergefahren wird, ist, dass noch eine Schleife läuft und die App zumindest theoretisch immer noch in der Lage ist, zusätzliche Anfragen zu verarbeiten (zusätzliche Aufrufe von handler.handle() ). Dies ist genau das gleiche Verhalten, das Sie auch auf den Servern von Amazon sehen würden: Die Lambda-Instanz läuft weiter, um weitere Anfragen zu verarbeiten, und wird irgendwann in der Zukunft gestoppt (gekillt), wenn Amazon Ressourcen freigeben möchte. Alle globalen Variablen werden über diese Aufrufe hinweg beibehalten. Wenn Sie einen MySQL-Verbindungspool haben, steht dieser Pool für den nächsten Lambda-Aufruf weiterhin zur Verfügung, was die Dinge merklich beschleunigt.

Sollte Serverless also den Prozess beenden, wenn der Funktionsaufruf abgeschlossen ist oder nicht? Ich weiß nicht. Aber nach der Antwort von @eahefnawy zum Schließen dieses Berichts zu urteilen, gehe ich davon aus, dass das erwartete Verhalten darin besteht, weiterzumachen.

Alle 3 Kommentare

Ich habe dies gerade mit 0.1.0 getestet und es verhält sich immer noch genauso: Das lokale Ausführen der Funktion (über sls function run component/module/func ) bleibt hängen und kehrt nicht zur Befehlszeile zurück, während die bereitgestellte Lambda-Funktion wie erwartet funktioniert.

gleiches Problem hier

Für alle, die dieses Problem immer noch haben ... Ich denke, es ist fraglich, ob dies ein Fehler ist oder nicht. Der Grund, warum sls nicht heruntergefahren wird, ist, dass noch eine Schleife läuft und die App zumindest theoretisch immer noch in der Lage ist, zusätzliche Anfragen zu verarbeiten (zusätzliche Aufrufe von handler.handle() ). Dies ist genau das gleiche Verhalten, das Sie auch auf den Servern von Amazon sehen würden: Die Lambda-Instanz läuft weiter, um weitere Anfragen zu verarbeiten, und wird irgendwann in der Zukunft gestoppt (gekillt), wenn Amazon Ressourcen freigeben möchte. Alle globalen Variablen werden über diese Aufrufe hinweg beibehalten. Wenn Sie einen MySQL-Verbindungspool haben, steht dieser Pool für den nächsten Lambda-Aufruf weiterhin zur Verfügung, was die Dinge merklich beschleunigt.

Sollte Serverless also den Prozess beenden, wenn der Funktionsaufruf abgeschlossen ist oder nicht? Ich weiß nicht. Aber nach der Antwort von @eahefnawy zum Schließen dieses Berichts zu urteilen, gehe ich davon aus, dass das erwartete Verhalten darin besteht, weiterzumachen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen