Beheben von Ausführungsproblemen in Lambda
Wenn die Lambda-Laufzeitumgebung Ihren Funktionscode ausführt, wird das Ereignis möglicherweise auf einer Instance der Funktion verarbeitet, auf der schon länger Ereignisse verarbeitet werden, oder muss möglicherweise eine neue Instance initialisiert werden. Fehler können während der Funktionsinitialisierung, wenn Ihr Handler-Code das Ereignis verarbeitet oder wenn Ihre Funktion eine Antwort zurückgibt (oder nicht zurückgibt), auftreten.
Funktionsausführungsfehler können durch Probleme mit Code, Funktionskonfiguration, nachgeschalteten Ressourcen oder Berechtigungen verursacht werden. Wenn Sie Ihre Funktion direkt aufrufen, sehen Sie Funktionsfehler in der Antwort von Lambda. Wenn Sie Ihre Funktion asynchron mit einer Ereignisquellen-Zuweisung oder über einen anderen Service aufrufen, finden Sie möglicherweise Fehler in Protokollen, eine Warteschlange für unzustellbare Nachrichten oder ein Ziel bei Ausfall. Die Optionen für die Fehlerbehandlung und das Wiederholungsverhalten variieren je nachdem, wie Sie Ihre Funktion aufrufen, und nach der Art des Fehlers.
Wenn Ihr Funktionscode oder die Lambda-Laufzeit einen Fehler zurückgibt, ist der Statuscode in der Antwort von Lambda „200 OK“. Das Vorhandensein eines Fehlers in der Antwort wird durch einen Header namens X-Amz-Function-Error angezeigt. Statuscodes der Serien 400 und 500 sind für Aufruffehler reserviert.
Themen
Lambda: Remote-Debugging mit Visual Studio Code
Problem: Schwierigkeiten bei der Fehlerbehebung im Zusammenhang mit dem Verhalten komplexer Lambda-Funktionen in der AWS-Umgebung
Lambda bietet ein Remote-Debugging-Feature über das AWS Toolkit for Visual Studio Code. Anweisungen zur Einrichtung und allgemeinen Nutzung finden Sie unter Remote-Debugging von Lambda-Funktionen mit Visual Studio Code.
Ausführliche Anweisungen zur Fehlerbehebung, zu erweiterten Anwendungsfällen und zur regionalen Verfügbarkeit finden Sie unter Remote-Debuggen von Lambda-Funktionen im AWS Toolkit for Visual Studio Code-Benutzerhandbuch.
Lambda: Die Ausführung dauert zu lange
Problem: Die Ausführung der Funktion dauert zu lange.
Wenn die Ausführung Ihres Codes in Lambda viel länger dauert als auf Ihrem lokalen Computer, kann er durch den der Funktion zur Verfügung stehenden Speicher oder die Rechenleistung eingeschränkt sein. Konfigurieren Sie die Funktion mit zusätzlichem Arbeitsspeicher, um sowohl Arbeitsspeicher als auch CPU zu erhöhen.
Lamda: Unerwartete Ereignis-Nutzdaten
Problem: Funktionsfehler im Zusammenhang mit fehlerhaftem JSON oder unzureichender Datenvalidierung
Alle Lambda-Funktionen erhalten eine Ereignis-Nutzdaten im ersten Parameter des Handlers. Die Ereignis- Nutzdaten sind eine JSON-Struktur, die Arrays und verschachtelte Elemente enthalten kann.
Missgebildetes JSON kann auftreten, wenn es von vorgelagerten Diensten bereitgestellt wird, die kein robustes Verfahren zur Überprüfung von JSON-Strukturen verwenden. Dies tritt auf, wenn Dienste Textzeichenfolgen miteinander verknüpfen oder Benutzereingaben einbetten, die nicht bereinigt wurden. JSON wird auch häufig für die Weitergabe zwischen Diensten serialisiert. Analysieren Sie JSON-Strukturen immer sowohl als Produzent als auch als Nutzer von JSON, um sicherzustellen, dass die Struktur gültig ist.
Ebenso kann es zu Fehlern kommen, wenn nicht auf Wertebereiche in den Ereignis-Nutzdaten geprüft wird. Eine Funktion, die an den Wert des Handlers übergeben wird:
exports.handler = async (event) => { let pct = event.taxPct let salary = event.salary // Calculate % of paycheck for taxes return (salary * pct) }
Diese Funktion verwendet ein Gehalt und einen Steuersatz aus den Ereignis-Nutzdaten, um die Berechnung durchzuführen. Der Code überprüft jedoch nicht, ob die Attribute vorhanden sind. Außerdem werden Datentypen nicht überprüft oder Grenzen nicht gewährleistet, z. B. die Sicherstellung, dass der Steuersatz zwischen 0 und 1 liegt. Daher führen Werte außerhalb dieser Grenzen zu unsinnigen Ergebnissen. Ein falscher Typ oder ein fehlendes Attribut führt zu einem Laufzeitfehler.
Erstellen Sie Tests, um sicherzustellen, dass Ihre Funktion größere Nutzdaten verarbeitet. Die maximale Größe für eine Lambda-Ereignis-Nutzlast beträgt 1 MB. Je nach Inhalt können größere Nutzdaten bedeuten, dass mehr Elemente an die Funktion übergeben werden oder dass mehr Binärdaten in ein JSON-Attribut eingebettet sind. In beiden Fällen kann dies zu mehr Verarbeitung für eine Lambda-Funktion führen.
Größere Nutzdaten können auch zu Timeouts führen. Eine Lambda-Funktion verarbeitet beispielsweise einen Datensatz pro 100 ms und hat ein Timeout von 3 Sekunden. Die Verarbeitung ist für 0-29 Elemente in den Nutzdaten erfolgreich. Sobald die Nutzdaten jedoch mehr als 30 Elemente enthalten, bricht die Funktion ab und gibt einen Fehler aus. Um dies zu vermeiden, stellen Sie sicher, dass die Timeouts so eingestellt sind, dass sie die zusätzliche Verarbeitungszeit für die maximale Anzahl erwarteter Elemente berücksichtigen.
Lambda: Unerwartet große Nutzdaten
Problem: Funktionen verursachen Timeouts und Fehler aufgrund großer Nutzdaten
Größere Nutzdaten können zu Timeouts und Fehlern führen. Wir empfehlen, Tests zu erstellen, um sicherzustellen, dass Ihre Funktion die größten zu erwartenden Nutzdaten verarbeiten kann, und zu prüfen, ob das Zeitlimit für die Funktion richtig eingestellt ist.
Darüber hinaus können bestimmte Ereignis-Nutzdaten Verweise auf andere Ressourcen enthalten. Beispielsweise kann eine Lambda-Funktion mit 128 MB Speicher eine Bildverarbeitung für eine JPG-Datei durchführen, die als Objekt in S3 gespeichert ist. Die Funktion funktioniert erwartungsgemäß mit kleineren Bilddateien. Wenn jedoch eine größere JPG-Datei als Eingabe bereitgestellt wird, gibt die Lambda-Funktion einen Fehler aus, da nicht genügend Speicherplatz zur Verfügung steht. Um dies zu vermeiden, sollten die Testfälle Beispiele aus dem oberen Bereich der erwarteten Datengrößen enthalten. Der Code sollte auch die Nutzdatengröße validieren.
Lambda: Fehler beim Kodieren und Dekodieren von JSON
Problem: NoSuchKey-Ausnahme beim Parsen von JSON-Eingaben
Stellen Sie sicher, dass Sie JSON-Attribute korrekt verarbeiten. Für Ereignisse, die von S3 generiert wurden, enthält das Attribut s3.object.key beispielsweise einen URL-codierten Objektschlüsselnamen. Viele Funktionen verarbeiten dieses Attribut als Text, um das referenzierte S3-Objekt zu laden:
const originalText = await s3.getObject({ Bucket: event.Records[0].s3.bucket.name, Key: event.Records[0].s3.object.key }).promise()
Dieser Code funktioniert mit dem Schlüsselnamen james.jpg, löst aber einen NoSuchKey-Fehler aus, wenn der Name james beswick.jpg lautet. Da die URL-Kodierung Leerzeichen und andere Zeichen in einem Schlüsselnamen konvertiert, müssen Sie sicherstellen, dass Funktionen Schlüssel dekodieren, bevor Sie diese Daten verwenden:
const originalText = await s3.getObject({ Bucket: event.Records[0].s3.bucket.name, Key: decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")) }).promise()
Lambda: Protokolle oder Ablaufverfolgungen erscheinen nicht
Problem: Protokolle werden in CloudWatch Logs nicht angezeigt.
Problem: Ablaufverfolgungen werden in nicht angezeigt AWS X-Ray.
Ihre Funktion benötigt die Berechtigung zum Aufrufen von CloudWatch Logs und X-Ray. Aktualisieren Sie die Ausführungsrolle, um ihr die Berechtigung zu erteilen. Fügen Sie die folgenden verwalteten Richtlinien hinzu, um Protokolle und Ablaufverfolgung zu aktivieren.
-
AWSLambdaBasicExecutionRole
-
AWSXRayDaemonWriteAccess
Wenn Sie Ihrer Funktion Berechtigungen hinzufügen, führen Sie auch eine triviale Aktualisierung ihres Codes oder ihrer Konfiguration durch. Dies zwingt ausgeführte Instances Ihrer Funktion, die veraltete Anmeldeinformationen haben, anzuhalten und ersetzt zu werden.
Anmerkung
Es kann 5 bis 10 Minuten dauern, bis Protokolle nach einem Funktionsaufruf angezeigt werden.
Lambda: Nicht alle Protokolle meiner Funktion werden angezeigt
Problem: In CloudWatch Logs fehlen Funktionsprotokolle, obwohl meine Berechtigungen korrekt sind
Wenn AWS-Konto die Kontingentgrenzen von CloudWatch Logs erreicht, drosselt CloudWatch die Funktionsprotokollierung. In diesem Fall werden einige der von Ihren Funktionen ausgegebenen Protokolle möglicherweise nicht in CloudWatch Logs angezeigt.
Wenn Ihre Funktion Protokolle schneller ausgibt, als Lambda sie verarbeiten kann, kann dies ebenfalls dazu führen, dass Protokollausgaben nicht in CloudWatch Logs erscheinen. Wenn Lambda Protokolle nicht mit der Geschwindigkeit an CloudWatch senden kann, mit der Ihre Funktion sie erzeugt, werden Protokolle gelöscht, um zu verhindern, dass die Ausführung der Funktion verlangsamt wird. Wenn Ihr Protokolldurchsatz 2 MB/s für einen einzelnen Protokollstrom übersteigt, müssen Sie damit rechnen, dass immer wieder Protokolle verloren gehen.
Wenn Ihre Funktion für die Verwendung von JSON-formatierten Protokollen konfiguriert ist, versucht Lambda, ein logsDropped-Ereignis an CloudWatch Logs zu senden, wenn es Protokolle fallen lässt. Wenn CloudWatch jedoch die Protokollierung Ihrer Funktion drosselt, kann es sein, dass dieses Ereignis CloudWatch Logs nicht erreicht, so dass Sie nicht immer einen Datensatz sehen, wenn Lambda Protokolle ablegt.
Gehen Sie wie folgt vor, um zu überprüfen, ob Ihr AWS-Konto das CloudWatch-Logs-Kontingent erreicht hat:
-
Öffnen Sie die Service Quotas-Konsole
. -
Wählen Sie im Navigationsbereich AWS-Services.
-
Wählen Sie in der Liste mit AWS-Services Amazon CloudWatch Logs aus.
-
Wählen Sie in der Liste mit den Service Quotas die Kontingente
CreateLogGroup throttle limit in transactions per second,CreateLogStream throttle limit in transactions per secondundPutLogEvents throttle limit in transactions per secondaus, um die Auslastung anzuzeigen.
Sie können sich von CloudWatch-Alarmen benachrichtigen lassen, wenn Ihre Kontonutzung ein von Ihnen festgelegtes Kontingentlimit überschreitet. Weitere Informationen finden Sie unter Erstellen eines CloudWatch-Alarms basierend auf einem statischen Schwellenwert.
Wenn die standardmäßigen Kontingentlimits für CloudWatch Logs für Ihren Anwendungsfall nicht ausreichen, können Sie eine Kontingenterhöhung beantragen.
Lambda: Die Funktion kehrt zurück, bevor die Ausführung beendet ist
Problem: (Node.js) Rückgabe der Funktion erfolgt, bevor Code ausgeführt wird
Viele Bibliotheken, einschließlich des AWS SDK, arbeiten asynchron. Wenn Sie einen Netzwerkaufruf tätigen oder einen anderen Vorgang ausführen, für den auf eine Antwort gewartet werden muss, geben Bibliotheken ein Objekt zurück, das als Zusage bezeichnet wird und mit dem der Status der Operation im Hintergrund nachverfolgt wird.
Um zu warten, bis die Zusage in eine Antwort aufgelöst wird, verwenden Sie das Schlüsselwort await. Dadurch wird verhindert, dass der Handler-Code ausgeführt wird, bis die Zusage in ein Objekt aufgelöst wird, das die Antwort enthält. Wenn Sie die Daten aus der Antwort in Ihrem Code nicht verwenden müssen, können Sie die Zusage direkt an die Laufzeit zurückgeben.
Einige Bibliotheken geben keine Zusagen zurück, können aber in Code verpackt werden, der dies tut. Weitere Informationen finden Sie unter Lambda-Funktionshandler in Node.js definieren.
Lamda: Ausführen einer unbeabsichtigten Funktionsversion oder eines Alias
Problem: Funktionsversion oder Alias wurde nicht aufgerufen
Wenn Sie neue Lambda-Funktionen in der Konsole oder mit AWS SAM veröffentlichen, wird die neueste Codeversion durch $LATEST dargestellt. Standardmäßig zielen Aufrufe, die keine Version oder keinen Alias angeben, automatisch auf die $LATEST-Version Ihres Funktionscodes ab.
Wenn Sie bestimmte Funktionsversionen oder Aliase verwenden, handelt es sich dabei um unveränderliche veröffentlichte Versionen einer Funktion zusätzlich zu $LATEST. Stellen Sie bei der Problembehebung dieser Funktionen zunächst fest, ob der Aufrufer die beabsichtigte Version oder den Alias aufgerufen hat. Überprüfen Sie dazu Ihre Funktionsprotokolle. Die Version der aufgerufenen Funktion wird immer in der START-Protokollzeile angezeigt:
Lambda: Erkennen von Endlosschleifen
Problem: Endlosschleifenmuster im Zusammenhang mit Lambda-Funktionen
Es gibt zwei Arten von Endlosschleifen in Lambda-Funktionen. Die erste befindet sich innerhalb der Funktion selbst und wird durch eine Schleife verursacht, die niemals beendet wird. Der Aufruf endet erst, wenn die Funktion ein Timeout verursacht. Sie können diese identifizieren, indem Sie Timeouts überwachen und dann das Schleifenverhalten beheben.
Die zweite Art von Schleife besteht zwischen Lambda-Funktionen und anderen AWS-Ressourcen. Diese treten auf, wenn ein Ereignis aus einer Ressource wie einem S3-Bucket eine Lambda-Funktion aufruft, die dann mit derselben Quellressource interagiert, um ein weiteres Ereignis auszulösen. Dadurch wird die Funktion erneut aufgerufen, wodurch eine weitere Interaktion mit demselben S3-Bucket erstellt wird, und so weiter. Diese Arten von Schleifen können durch eine Reihe verschiedener AWS-Ereignisquellen verursacht werden, darunter Amazon-SQS-Warteschlangen und DynamoDB-Tabellen. Sie können diese Muster mithilfe der rekursiven Schleifenerkennung identifizieren.
Sie können diese Schleifen vermeiden, indem Sie sicherstellen, dass Lambda-Funktionen in Ressourcen schreiben, die nicht mit der verbrauchenden Ressource identisch sind. Wenn Sie Daten wieder auf der verbrauchenden Ressource veröffentlichen müssen, stellen Sie sicher, dass die neuen Daten nicht dasselbe Ereignis auslösen. Verwenden Sie alternativ die Ereignisfilterung. Hier sind beispielsweise zwei Lösungsvorschläge für Endlosschleifen mit S3- und DynamoDB-Ressourcen:
-
Wenn Sie in denselben S3-Bucket zurückschreiben, verwenden Sie ein anderes Präfix oder Suffix als beim Ereignisauslöser.
-
Wenn Sie Elemente in dieselbe DynamoDB-Tabelle schreiben, fügen Sie ein Attribut hinzu, nach dem eine verbrauchende Lambda-Funktion filtern kann. Wenn Lambda das Attribut findet, führt dies nicht zu einem weiteren Aufruf.
Allgemein: Nichtverfügbarkeit nachgelagerter Dienste
Problem: Die nachgelagerten Dienste, auf die Ihre Lambda-Funktion angewiesen ist, sind nicht verfügbar
Stellen Sie bei Lambda-Funktionen, die Drittanbieter-Endpunkte oder andere nachgelagerte Ressourcen aufrufen, sicher, dass sie Servicefehler und Timeouts behandeln können. Diese nachgelagerten Ressourcen können unterschiedliche Reaktionszeiten haben oder aufgrund von Serviceunterbrechungen nicht verfügbar sein. Je nach Implementierung können diese nachgelagerten Fehler als Lambda-Timeouts oder Ausnahmen erscheinen, wenn die Fehlerantwort des Dienstes nicht im Code der Funktion behandelt wird.
Implementieren Sie eine geeignete Fehlerbehandlung und Wiederholungslogik, wenn eine Funktion von einem nachgelagerten Dienst abhängt, z. B. von einem API-Aufruf. Für kritische Dienste sollte die Lambda-Funktion Metriken oder Protokolle in CloudWatch veröffentlichen. Wenn beispielsweise eine Zahlungs-API eines Drittanbieters nicht mehr verfügbar ist, kann die Lambda-Funktion diese Informationen protokollieren. Anschließend können Sie CloudWatch-Warnmeldungen einrichten, um Benachrichtigungen zu diesen Fehlern zu senden.
Da Lambda schnell skalieren kann, können nachgelagerte Dienste, die nicht Serverless sind, Schwierigkeiten haben, Datenverkehrsspitzen zu bewältigen. Es gibt drei gängige Ansätze, um damit umzugehen:
-
Caching: Erwägen Sie, die Ergebnisse von Werten, die von Drittanbieterdiensten zurückgegeben werden, zwischenzuspeichern, wenn diese sich nicht häufig ändern. Sie können diese Werte in einer globalen Variablen in Ihrer Funktion oder einem anderen Dienst speichern. Beispielsweise könnten die Ergebnisse einer Produktlistenabfrage von einer Amazon RDS-Instance innerhalb der Funktion für einen bestimmten Zeitraum gespeichert werden, um redundante Abfragen zu vermeiden.
-
Warteschlangen: Fügen Sie beim Speichern oder Aktualisieren von Daten eine Amazon-SQS-Warteschlange zwischen der Lambda-Funktion und der Ressource hinzu. In der Warteschlange werden Daten dauerhaft gespeichert, während der nachgelagerte Dienst Nachrichten verarbeitet.
-
Proxys: Wenn in der Regel langlebige Verbindungen verwendet werden, z. B. für Amazon-RDS-Instances, verwenden Sie eine Proxyebene, um diese Verbindungen zu bündeln und wiederzuverwenden. Für relationale Datenbanken ist Amazon-RDS-Proxy
ein Service, der dazu beitragen soll, die Skalierbarkeit und Stabilität von Lambda–basierten Anwendungen zu verbessern.
AWS SDK: Versionen und Updates
Problem: Das in der Laufzeit enthaltene AWS SDK ist nicht die neueste Version
Problem: Das in den Laufzeitaktualisierungen enthaltene AWS SDK wird automatisch aktualisiert
Die Laufzeiten für interpretierte Sprachen enthalten eine Version des AWS SDK. Lambda aktualisiert diese Laufzeiten regelmäßig, um die neueste SDK-Version zu verwenden. Die in Ihrer Laufzeit enthaltene SDK-Version finden Sie in den folgenden Abschnitten:
Um eine neuere Version des AWS SDK zu verwenden oder Ihre Funktionen auf eine bestimmte Version zu fixieren, können Sie die Bibliothek mit Ihrem Funktionscode bündeln oder eine Lambda-Ebene erstellen. Weitere Informationen zum Erstellen eines Bereitstellungspakets mit Abhängigkeiten finden Sie in den folgenden Themen:
Python: Bibliotheken werden falsch geladen
Problem: (Python) Einige Bibliotheken werden nicht korrekt aus dem Bereitstellungspaket geladen
Bibliotheken mit Erweiterungsmodulen, die in C oder C ++ geschrieben sind, müssen in einer Umgebung mit derselben Prozessorarchitektur wie Lambda (Amazon Linux) kompiliert werden. Weitere Informationen finden Sie unter Arbeiten mit ZIP-Dateiarchiven und Python-Lambda-Funktionen.
Java: Ihre Funktion braucht länger, um Ereignisse zu verarbeiten, nachdem sie von Java 11 auf Java 17 aktualisiert wurde
Problem: (Java) Ihre Funktion braucht länger, um Ereignisse zu verarbeiten, nachdem sie von Java 11 auf Java 17 aktualisiert wurde
Optimieren Sie Ihren Compiler mithilfe des JAVA_TOOL_OPTIONS-Parameters. Lambda-Laufzeiten für Java 17 und spätere Java-Versionen ändern die Standard-Compileroptionen. Die Änderung verbessert die Kaltstartzeiten für kurzlebige Funktionen, aber das bisherige Verhalten ist besser für rechenintensive, länger laufende Funktionen geeignet. Setzen Sie JAVA_TOOL_OPTIONS auf -XX:-TieredCompilation, um zum Verhalten von Java 11 zurückzukehren. Weitere Informationen zum Parameter JAVA_TOOL_OPTIONS erhalten Sie unter Die JAVA_TOOL_OPTIONS-Umgebungsvariable verstehen.