AWS Lambda RDS-Verbindungszeitüberschreitung

8

Ich versuche eine Lambda-Funktion mit Node.js zu schreiben, die sich mit meiner RDS-Datenbank verbindet. Die Datenbank funktioniert und ist über meine Elastic Beanstalk-Umgebung zugänglich. Wenn ich die Funktion ausführe, wird ein Timeout-Fehler zurückgegeben.

Es wurde versucht, den Timeout um bis zu 5 Minuten mit exakt demselben Ergebnis zu erhöhen.

Nach einigen Nachforschungen kam ich zu dem Schluss, dass es sich wahrscheinlich um ein Sicherheitsproblem handelt, aber die Lösung in der Dokumentation von Amazon oder in diese Antwort (die einzige, die ich zu dem Thema finden konnte).

Hier sind die Sicherheitsdetails:

  • Sowohl RDS als auch Lambda befinden sich in derselben Sicherheitsgruppe.
  • Der RDS hat alle ein- und ausgehenden Regeln für den Datenverkehr.
  • Das Lambda hat die AmazonVPCFullAccess-Richtlinie in seiner Rolle.

Mein Code ist:

%Vor%

Das Ergebnis, das ich bekomme, ist:

%Vor%     
Sir Codesalot 05.03.2017, 06:07
quelle

7 Antworten

7

Ich möchte allen danken, die geholfen haben, das Problem stellte sich als anders heraus, als ich dachte. Das callback im Code funktioniert aus irgendeinem Grund nicht, obwohl es in AMAZON'S EIGENE VORGABEN SAMPLE ist.

Der Arbeitscode sieht so aus:

%Vor%     
Sir Codesalot 06.03.2017, 06:39
quelle
10

Während die Verwendung des Kontexts funktioniert, müssen Sie nur context.callbackWaitsForEmptyEventLoop = false; zum Handler hinzufügen und dann den Callback wie folgt verwenden:

%Vor%

Die Antwort ist hier in der Dokumentation (brauchte ein paar Stunden, um das zu finden): Ссылка

Im Abschnitt "Vergleich der Kontext- und Rückrufmethoden" gibt es einen Hinweis "Wichtig", der die Dinge erklärt.

Am Ende der Notiz steht:

  

Wenn Sie also dasselbe Verhalten wie die Kontextmethoden möchten, müssen Sie die Eigenschaft context object, callbackWaitsForEmptyEventLoop, auf false setzen.

Grundsätzlich wird der Rückruf bis zum Ende der Ereignisschleife fortgesetzt, im Gegensatz zum Kontext, der die Ereignisschleife beendet. Wenn callbackWaitsForEmptyEventLoop gesetzt wird, funktioniert Callback wie ein Kontext.

    
ambaum2 17.07.2017 15:07
quelle
2

Ich teile meine Erfahrung beim Verbinden von RDS.

  

Sie müssen VPC access für Lambda function aktivieren, während dem Sie ihm eine Sicherheitsgruppe .

Anschließend aktivieren Sie in der Sicherheitsgruppe, die der RDS-Instanz zugewiesen ist, den Zugriff für die der Lambda-Funktion zugewiesene Sicherheitsgruppe.

Sie können weitere Informationen hier

erhalten     
abdulbarik 05.03.2017 07:15
quelle
1

Wenn Sie die Datenbank ursprünglich eingerichtet haben, wird automatisch eine Sicherheitsgruppe erstellt. Standard auf die IP, mit der Sie die DB eingerichtet haben. Wenn Sie von Lambda starten, blockiert diese Regel den Datenverkehr. Überprüfen Sie Ihre Db-Fehlerprotokolle, und Sie können bestätigen, dass die Verbindung abgewiesen wird.

%Vor%

Sie müssen eine Regel in der Sicherheitsgruppe erstellen, um Lambda-Verkehr zuzulassen. Wechseln Sie zu Ihrer RDS-Instanzkonsole, klicken Sie auf die Sicherheitsgruppe und wählen Sie Eingang aus. Dort sehen Sie die Regeln. Dann machen Sie den Anruf, um sich für die Welt zu öffnen, die AWS Lambda IPs zu finden oder eine VPC zu erstellen.

    
toonsend 31.01.2018 10:48
quelle
0
  
    
      

Sowohl der RDS als auch der Lambda befinden sich in derselben Sicherheitsgruppe.

    
  

Das ist der Schlüssel. Standardmäßig ist die Kommunikation innerhalb derselben Sicherheitsgruppe nicht zulässig. Und Sie müssen es explizit zulassen (E.x sg-xxxxx ALL TCP). Dies funktioniert nur, wenn Ihr Lambda versucht, über private IP auf db zuzugreifen.

Wenn es versucht, es durch öffentliche IP zu erreichen, dass es nicht funktioniert und Sie dafür notwendige Löcher auch schlagen müssen.

Allerdings gibt es einen besseren Ansatz:

  1. Erstellen Sie separate separate Sicherheitsgruppe für Ihr Lambda
  2. Erlaube eingehenden Datenverkehr auf Port 3306 in RDS sg für lambdas sg.
Vor 05.03.2017 17:49
quelle
0

Das Problem stammt nicht vom Timeout, sondern von der Art, wie Sie die Verbindung schließen. Verwenden Sie stattdessen .destroy() , wenn Sie nicht auf den Rückruf warten wollen, ODER verwenden Sie den Rückruf korrekt, wenn Sie die Verbindung in .end(function(err) { //Now call your callback });

schließen

Weitere Informationen finden Sie in diesem Thread .

    
DR. 06.06.2017 07:18
quelle
0

Ich habe auch ein ähnliches Timeout-Szenario erlebt. Problem nicht connection.end() nach connection.connect() . Connection.end() sollte vor callback erfolgen.

Arbeitscode:

%Vor%     
user2735676 24.12.2017 07:04
quelle