Verwenden Sie die rekursive Lambda-Schleifenerkennung, um Endlosschleifen zu verhindern - AWS Lambda

Verwenden Sie die rekursive Lambda-Schleifenerkennung, um Endlosschleifen zu verhindern

Wenn Sie als Ziel für die Ausgabe einer Lambda-Funktion den gleichen Service oder die gleiche Ressource konfigurieren, durch den bzw. durch die die Funktion aufgerufen wird, kann eine unendliche rekursive Schleife entstehen. Ein Beispiel wäre etwa eine Lambda-Funktion, die eine Nachricht in eine Amazon Simple Queue Service (Amazon SQS)-Warteschlange schreibt, die wiederum die gleiche Funktion aufruft. Dieser Aufruf veranlasst die Funktion, eine weitere Nachricht in die Warteschlange zu schreiben, die wiederum erneut die Funktion aufruft.

Unbeabsichtigte rekursive Schleifen können zu unerwarteten Gebühren für Ihr AWS-Konto führen. Außerdem können Schleifen dazu führen, dass Lambda skaliert wird und die gesamte verfügbare Parallelität Ihres Kontos nutzt. Um die Auswirkungen unbeabsichtigter Schleifen zu verringern, erkennt Lambda bestimmte Arten von rekursiven Schleifen kurz nach ihrem Auftreten. Wenn Lambda eine rekursive Schleife erkennt, wird der Aufruf Ihrer Funktion standardmäßig gestoppt und Sie werden benachrichtigt. Wenn Ihr Entwurf bewusst rekursive Muster verwendet, können Sie die Standardkonfiguration einer Funktion so ändern, dass sie rekursiv aufgerufen werden kann. Weitere Informationen finden Sie unter Zulassen, dass eine Lambda-Funktion in einer rekursiven Schleife ausgeführt wird.

Grundlegendes zur Erkennung rekursiver Schleifen

Zur Erkennung rekursiver Schleifen in Lambda werden Ereignisse nachverfolgt. Lambda ist ein ereignisgesteuerter Compute-Service, der Ihren Funktionscode ausführt, wenn bestimmte Ereignisse auftreten. Ein Beispiel wäre etwa das Hinzufügen eines Elements zu einer Amazon-SQS-Warteschlange oder zu einem Amazon Simple Notification Service (Amazon SNS)-Thema. Ereignisse werden von Lambda als JSON-Objekte mit Informationen zur Änderung des Systemstatus an Ihre Funktion übergeben. Die Ausführung Ihrer Funktion infolge eines Ereignisses wird als Aufruf bezeichnet.

Zur Erkennung rekursiver Schleifen verwendet Lambda AWS X-Ray-Ablaufverfolgungs-Header. Wenn AWS-Services, die die Erkennung rekursiver Schleifen unterstützen, Ereignisse an Lambda senden, werden diese Ereignisse automatisch mit Metadaten versehen. Wenn Ihre Lambda-Funktion eines dieser Ereignisse in einen anderen unterstützten AWS-Service schreibt und dabei eine unterstützte Version eines AWS SDK verwendet, werden diese Metadaten aktualisiert. In den aktualisierten Metadaten ist angegeben, wie oft das Ereignis die Funktion aufgerufen hat.

Anmerkung

Dieses Feature funktioniert ohne Aktivierung der aktiven X-Ray-Ablaufverfolgung. Die Erkennung rekursiver Schleifen ist standardmäßig für alle AWS-Kunden aktiviert. Die Nutzung des Features ist kostenlos.

Bei einer Kette von Anforderungen handelt es sich um eine Sequenz von Lambda-Aufrufen, die durch das gleiche auslösende Ereignis verursacht werden. Ein Beispiel: Angenommen, eine Amazon-SQS-Warteschlange ruft Ihre Lambda-Funktion auf. Anschließend sendet Ihre Lambda-Funktion das verarbeitete Ereignis an die gleiche Amazon-SQS-Warteschlange zurück und diese ruft wiederum erneut Ihre Funktion auf. In diesem Beispiel gehört jeder Aufruf Ihrer Funktion zur gleichen Kette von Anforderungen.

Wenn Ihre Funktion ungefähr 16-mal in der gleichen Kette von Anforderungen aufgerufen wird, beendet Lambda automatisch den nächsten Funktionsaufruf in dieser Anforderungskette und benachrichtigt Sie. Wenn Ihre Funktion mit mehreren Auslösern konfiguriert ist, sind Aufrufe von anderen Auslösern nicht betroffen.

Anmerkung

Selbst wenn die maxReceiveCount-Einstellung in der Redrive-Richtlinie der Quellwarteschlange höher als 16 ist, verhindert der Lambda-Rekursionsschutz nicht, dass Amazon SQS die Nachricht erneut versucht, nachdem eine rekursive Schleife erkannt und beendet wurde. Wenn Lambda eine rekursive Schleife erkennt und nachfolgende Aufrufe abbricht, gibt es ein RecursiveInvocationException an die Zuordnung von Ereignisquellen zurück. Dadurch wird der receiveCount-Wert in der Nachricht erhöht. Lambda versucht weiterhin, die Nachricht zu wiederholen, und blockiert weiterhin Funktionsaufrufe, bis Amazon SQS feststellt, dass das maxReceiveCount überschritten wurde, und die Nachricht an die konfigurierte Warteschlange für unzustellbare Nachrichten sendet.

Wenn Sie für Ihre Funktion ein Ziel bei Ausfall oder eine Warteschlange für unzustellbare Nachrichten konfiguriert haben, sendet Lambda das Ereignis aus dem beendeten Aufruf auch an Ihr Ziel oder an die Warteschlange für unzustellbare Nachrichten. Wenn Sie für Ihre Funktion ein Ziel oder eine Warteschlange für unzustellbare Nachrichten konfigurieren, achten Sie darauf, keinen Ereignisauslöser und keine Zuordnung von Ereignisquellen zu verwenden, die Ihre Funktion auch verwendet. Wenn Sie Ereignisse an die Ressource senden, die auch Ihre Funktion aufruft, können Sie eine weitere rekursive Schleife erstellen und diese Schleife wird auch beendet. Wenn Sie die Rekursionsschleifenerkennung deaktivieren, wird diese Schleife nicht beendet.

Unterstützte AWS-Services und SDKs

Lambda kann nur rekursive Schleifen erkennen, die bestimmte unterstützte AWS-Services enthalten. Für die Erkennung rekursiver Schleifen muss Ihre Funktion außerdem eines der unterstützten AWS SDKs verwenden.

Unterstützt AWS-Services

Lambda erkennt derzeit rekursive Schleifen zwischen Funktionen, Amazon SQS, Amazon S3 und Amazon SNS. Außerdem erkennt Lambda Schleifen, die nur aus Lambda-Funktionen bestehen, die sich synchron oder asynchron gegenseitig aufrufen. Die folgenden Diagramme zeigen einige Beispiele für Schleifen, die von Lambda erkannt werden:

Diagramme rekursiver Schleifen zwischen einer Lambda-Funktion, Amazon SNS, Amazon S3 und einer Amazon-SQS-Warteschlange.

Wenn ein anderer AWS-Service – etwa Amazon DynamoDB Teil der Schleife ist, kann sie derzeit nicht von Lambda erkannt und beendet werden.

Da Lambda derzeit nur rekursive Schleifen mit Amazon SQS, Amazon S3 und Amazon SNS erkennt, kann es vorkommen, dass Schleifen, an denen andere AWS-Services beteiligt sind, zu einer unbeabsichtigten Verwendung Ihrer Lambda-Funktionen führen.

Um der Entstehung unerwarteter Gebühren für Ihr AWS-Konto vorzubeugen, empfiehlt es sich, Amazon-CloudWatch-Alarme zu konfigurieren, die Sie auf ungewöhnliche Nutzungsmuster aufmerksam machen. Sie können CloudWatch beispielsweise so konfigurieren, dass Sie über Spitzen bei der Parallelität oder bei Aufrufen von Lambda-Funktionen informiert werden. Des Weiteren können Sie einen Abrechnungsalarm konfigurieren, um benachrichtigt zu werden, wenn die Ausgaben für Ihr Konto einen von Ihnen angegebenen Schwellenwert übersteigen. Eine weitere Möglichkeit ist die Verwendung der AWS Cost Anomaly Detection, um über ungewöhnliche Abrechnungsmuster informiert zu werden.

Unterstützte AWS SDKs

Damit Lambda rekursive Schleifen erkennt, muss Ihre Funktion eine der folgenden SDK-Mindestversionen verwenden:

Laufzeit Erforderliche Mindestversion des AWS SDK

Node.js

2.1147.0 (SDK-Version 2)

3.105.0 (SDK-Version 3)

Python

1.24.46 (boto3)

1.27.46 (botocore)

Java 8 und Java 11

2.17.135

Java 17

2.20.81

Java 21

2.21.24

.NET

3.7.293.0

Ruby

3.134.0

PHP

3.232.0

Go

V2 SDK 1.57.0

Einige Lambda-Laufzeiten wie Python und Node.js enthalten eine Version des AWS SDK. Wenn die in der Laufzeit Ihrer Funktion enthaltene SDK-Version kleiner ist als die erforderliche Mindestversion, können Sie dem Bereitstellungspaket Ihrer Funktion eine unterstützte Version des SDK hinzufügen. Sie können auch eine Lambda-Ebene verwenden, um Ihrer Funktion eine unterstützte SDK-Version hinzuzufügen. Eine Liste der SDKs, die in der jeweiligen Lambda-Laufzeitumgebung enthalten sind, finden Sie unter Lambda-Laufzeiten.

Benachrichtigungen zu rekursiven Schleifen

Wenn Lambda eine rekursive Schleife beendet, erhalten Sie Benachrichtigungen über das AWS Health Dashboard und per E-Mail. Sie können auch CloudWatch-Metriken verwenden, um die Anzahl rekursiver Aufrufe zu überwachen, die von Lambda beendet wurden.

Benachrichtigungen über das AWS Health Dashboard

Wenn Lambda einen rekursiven Aufruf beendet, wird auf dem AWS Health Dashboard auf der Seite Ihr Kontostatus unter Offene und aktuelle Probleme eine Benachrichtigung angezeigt. Beachten Sie, dass es nach der Beendigung eines rekursiven Aufrufs durch Lambda bis zu 3,5 Stunden dauern kann, bis diese Benachrichtigung angezeigt wird. Weitere Informationen zum Anzeigen von Kontoereignissen auf dem AWS Health Dashboard finden Sie im AWS-Health-Benutzerhandbuch unter Getting started with your AWS Health Dashboard – Your account health.

E-Mail-Benachrichtigungen

Wenn Lambda zum ersten Mal einen rekursiven Aufruf Ihrer Funktion beendet, erhalten Sie eine E-Mail-Benachrichtigung. Für jede Funktion in Ihrem AWS-Konto wird alle 24 Stunden maximal eine E-Mail gesendet. Nachdem Lambda eine E-Mail-Benachrichtigung gesendet hat, erhalten Sie für einen Zeitraum von 24 Stunden keine E-Mails mehr zu dieser Funktion. Das gilt auch, wenn Lambda weitere rekursive Aufrufe der Funktion beendet. Beachten Sie, dass es nach der Beendigung eines rekursiven Aufrufs durch Lambda bis zu 3,5 Stunden dauern kann, bis Sie diese E-Mail-Benachrichtigung erhalten.

Lambda sendet E-Mail-Benachrichtigungen zu rekursiven Schleifen an den primären Kontokontakt Ihres AWS-Kontos sowie an den alternativen Kontakt für den Betrieb. Informationen zum Anzeigen oder Aktualisieren der E-Mail-Adressen in Ihrem Konto finden Sie in der allgemeinen AWS-Referenz unter Updating contact information.

Amazon CloudWatch-Metriken

Die CloudWatch-Metrik RecursiveInvocationsDropped zeichnet die Anzahl der Funktionsaufrufe auf, die von Lambda beendet wurden, weil Ihre Funktion in einer einzelnen Kette von Anforderungen mehr als 16-mal aufgerufen wurde. Lambda gibt diese Metrik aus, sobald ein rekursiver Aufruf beendet wurde. Gehen Sie zum Anzeigen dieser Metrik gemäß der Anleitung unter Anzeigen von Metriken in der CloudWatch-Konsole vor und wählen Sie die Metrik RecursiveInvocationsDropped aus.

Reagieren auf Benachrichtigungen im Zusammenhang mit der Erkennung rekursiver Schleifen

Wenn Ihre Funktion etwa mehr als 16-mal durch das gleiche auslösende Ereignis aufgerufen wird, beendet Lambda den nächsten Funktionsaufruf für dieses Ereignis, um die rekursive Schleife zu unterbrechen. Gehen Sie wie folgt vor, um zu verhindern, dass eine rekursive Schleife, die von Lambda unterbrochen wurde, erneut auftritt:

  • Reduzieren Sie die verfügbare Parallelität Ihrer Funktion auf Null. Dadurch werden alle zukünftigen Aufrufe gedrosselt.

  • Entfernen oder deaktivieren Sie den Auslöser oder die Zuordnung von Ereignisquellen, der bzw. die Ihre Funktion aufruft.

  • Identifizieren und beheben Sie Codefehler, die Ereignisse an die AWS-Ressource zurückschreiben, die Ihre Funktion aufruft. Eine Fehlerquelle entsteht häufig, wenn die Ereignisquelle und das Ziel einer Funktion mithilfe von Variablen definiert werden. Achten Sie darauf, nicht für beide Variablen den gleichen Wert zu verwenden.

Wenn die Ereignisquelle für Ihre Lambda-Funktion eine Amazon-SQS-Warteschlange ist, empfiehlt es sich außerdem gegebenenfalls, für die Quellwarteschlange eine Warteschlange für unzustellbare Nachrichten zu konfigurieren.

Anmerkung

Achten Sie darauf, die Warteschlange für unzustellbare Nachrichten für die Quellwarteschlange und nicht für die Lambda-Funktion zu konfigurieren. Die Warteschlange für unzustellbare Nachrichten, die Sie für eine Funktion konfigurieren, wird für die Warteschlange asynchroner Aufrufe der Funktion und nicht für Ereignisquellen-Warteschlangen verwendet.

Wenn es sich bei der Ereignisquelle um ein Amazon-SNS-Thema handelt, empfiehlt es sich gegebenenfalls, für Ihre Funktion ein Ziel bei Ausfall hinzuzufügen.

So reduzieren Sie die verfügbare Parallelität Ihrer Funktion auf Null (Konsole)
  1. Öffnen Sie die Seite Funktionen der Lambda-Konsole.

  2. Wählen Sie den Namen Ihrer Funktion aus.

  3. Wählen Sie Drosseln aus.

  4. Wählen Sie im Dialogfeld Funktion drosseln die Option Bestätigen aus.

So entfernen Sie einen Auslöser oder eine Zuordnung von Ereignisquellen für Ihre Funktion (Konsole)
  1. Öffnen Sie die Seite Funktionen der Lambda-Konsole.

  2. Wählen Sie den Namen Ihrer Funktion aus.

  3. Wählen Sie die Registerkarte Konfiguration und anschließend Auslöser aus.

  4. Wählen Sie unter Auslöser den Auslöser oder die Zuordnung von Ereignisquellen aus, den bzw. die Sie löschen möchten, und wählen Sie anschließend Löschen aus.

  5. Wählen Sie im Dialogfeld Auslöser löschen die Option Löschen aus.

So deaktivieren Sie eine Zuordnung von Ereignisquellen für Ihre Funktion (AWS CLI)
  1. Führen Sie über die AWS Command Line Interface (AWS CLI) den Befehl list-event-source-mappings aus, um die UUID für die Zuordnung von Ereignisquellen zu ermitteln, die Sie deaktivieren möchten.

    aws lambda list-event-source-mappings
  2. Führen Sie über die AWS CLI den folgenden Befehl vom Typ update-event-source-mapping aus, um die Zuordnung von Ereignisquellen zu deaktivieren:

    aws lambda update-event-source-mapping --function-name MyFunction \ --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 --no-enabled

Zulassen, dass eine Lambda-Funktion in einer rekursiven Schleife ausgeführt wird

Wenn Ihr Entwurf absichtlich eine rekursive Schleife verwendet, können Sie eine Lambda-Funktion so konfigurieren, dass sie rekursiv aufgerufen werden kann. Wir empfehlen, dass Sie rekursive Schleifen in Ihrem Entwurf vermeiden. Implementierungsfehler können zu rekursiven Aufrufen führen, die die gesamte verfügbare Gleichzeitigkeit Ihres AWS-Konto nutzen und zu unerwarteten Kosten, die Ihrem Konto in Rechnung gestellt werden.

Wichtig

Wenn Sie rekursive Schleifen verwenden, sollten Sie diese mit Vorsicht behandeln. Implementieren Sie bewährte Leitplanken, um das Risiko von Implementierungsfehlern zu minimieren. Weitere Informationen zu bewährten Methoden für die Verwendung rekursiver Muster finden Sie bei Serverless Land unter Recursive patterns that cause run-away Lambda functions.

Sie können Funktionen so konfigurieren, dass sie rekursive Schleifen zulassen, indem Sie die Lambda-Konsole, die AWS Command Line Interface (AWS CLI) und die PutFunctionRecursionConfig-API verwenden. Sie können auch die Einstellung für die Erkennung rekursiver Schleifen einer Funktion in AWS SAM und CloudFormation konfigurieren.

Standardmäßig erkennt und beendet Lambda rekursive Schleifen. Sofern Ihr Entwurf nicht bewusst eine rekursive Schleife verwendet, empfehlen wir Ihnen, die Standardkonfiguration Ihrer Funktionen nicht zu ändern.

Beachten Sie, dass die CloudWatch-Metrik RecursiveInvocationsDropped nicht ausgegeben wird, wenn Sie eine Funktion so konfigurieren, dass sie rekursive Schleifen zulässt.

Console
So können Sie eine Funktion in einer rekursiven Schleife ausführen (Konsole)
  1. Öffnen Sie die Seite Funktionen der Lambda-Konsole.

  2. Wählen Sie den Namen Ihrer Funktion, um die Funktionsdetailseite zu öffnen.

  3. Wählen Sie die Registerkarte Konfiguration und anschließend Gleichzeitigkeit und Rekursionserkennung.

  4. Wählen Sie neben Rekursive Schleifenerkennung die Option Bearbeiten aus.

  5. Wählen Sie Rekursive Schleifen zulassen aus.

  6. Wählen Sie Speichern.

AWS CLI

Sie können die PutFunctionRecursionConfig-API verwenden, um zu ermöglichen, dass Ihre Funktion in einer rekursiven Schleife aufgerufen wird. Geben Sie Allow als Parameter für die rekursive Schleife an. Sie können diese API beispielsweise mit dem put-function-recursion-config AWS CLI Befehl aufrufen:

aws lambda put-function-recursion-config --function-name yourFunctionName --recursive-loop Allow

Sie können die Konfiguration Ihrer Funktion auf die Standardeinstellung zurücksetzen, sodass Lambda rekursive Schleifen beendet, wenn es sie erkennt. Bearbeiten Sie die Konfiguration Ihrer Funktion mit der Lambda-Konsole oder dem AWS CLI.

Console
So konfigurieren Sie eine Funktion so, dass rekursive Schleifen abgebrochen werden (Konsole)
  1. Öffnen Sie die Seite Funktionen der Lambda-Konsole.

  2. Wählen Sie den Namen Ihrer Funktion, um die Funktionsdetailseite zu öffnen.

  3. Wählen Sie die Registerkarte Konfiguration und anschließend Gleichzeitigkeit und Rekursionserkennung.

  4. Wählen Sie neben Rekursive Schleifenerkennung die Option Bearbeiten aus.

  5. Wählen Sie Rekursive Schleifen beenden aus.

  6. Wählen Sie Speichern.

AWS CLI

Sie können die PutFunctionRecursionConfig-API verwenden, um Ihre Funktion so zu konfigurieren, dass Lambda rekursive Schleifen beendet, wenn es sie erkennt. Geben Sie Terminate als Parameter für die rekursive Schleife an. Sie können diese API beispielsweise mit dem put-function-recursion-config AWS CLI Befehl aufrufen:

aws lambda put-function-recursion-config --function-name yourFunctionName --recursive-loop Terminate

Unterstützte Regionen für die Erkennung rekursiver Lambda-Schleifen

Die Lambda-Rekursivschleifenerkennung wird in allen Handelsregionen außer Mexiko (Zentral) und Asien-Pazifik (Neuseeland) unterstützt.