Wie behebe ich Probleme mit Wiederholungsversuchen und Timeouts, wenn ich eine Lambda-Funktion mithilfe eines AWS-SDK aufrufe?
Wenn ich meine AWS Lambda-Funktion mithilfe eines AWS-SDK aufrufe, läuft die Funktion ab, die API-Anfrage reagiert nicht mehr oder eine API-Aktion wird dupliziert. Wie behebe ich diese Probleme?
Kurzbeschreibung
Es gibt drei Gründe, warum Wiederholungs- und Timeout-Probleme auftreten, wenn eine Lambda-Funktion mit einem AWS-SDK aufgerufen wird:
- Eine Remote-API ist nicht erreichbar oder es dauert zu lange, bis sie auf einen API-Aufruf reagiert.
- Der API-Aufruf erhält innerhalb des Socket-Timeouts keine Antwort.
- Der API-Aufruf erhält innerhalb des Timeout-Zeitraums der Lambda-Funktion keine Antwort.
Hinweis: API-Aufrufe können länger als erwartet dauern, wenn Netzwerkverbindungsprobleme auftreten. Netzwerkprobleme können auch zu Wiederholungsversuchen und doppelten API-Anfragen führen. Um sich auf diese Ereignisse vorzubereiten, stellen Sie sicher, dass Ihre Lambda-Funktion idempotent ist.
Wenn Sie einen API-Aufruf mit einem AWS-SDK tätigen und der Aufruf fehlschlägt, versucht das AWS-SDK den Aufruf automatisch erneut. Wie oft und wie lange das AWS-SDK wiederholt, hängt von den Einstellungen ab, die von AWS-SDK zu AWS-SDK variieren.
Standardeinstellungen für AWS-SDK-Wiederholungen
Hinweis: Einige Werte können für andere AWS-Services unterschiedlich sein.
AWS SDK | Maximale Anzahl an Wiederholungen | Verbindungs-Timeout | Socket-Timeout |
Python (Boto 3) | hängt vom Service ab | 60 Sekunden | 60 Sekunden |
JavaScript/Node.js | hängt vom Service ab | N/A | 120 Sekunden |
Java | 3 | 10 Sekunden | 50 Sekunden |
.NET | 4 | 100 Sekunden | 300 Sekunden |
Go | 3 | N/A | N/A |
Um die Probleme mit Wiederholungsversuchen und Timeout zu beheben, überprüfen Sie zunächst die Protokolle des API-Aufrufs, um das Problem zu finden. Ändern Sie dann die Anzahl der Wiederholungsversuche und die Timeout-Einstellungen des AWS-SDK nach Bedarf für jeden Anwendungsfall. Um genügend Zeit für eine Antwort auf den API-Aufruf zu haben, fügen Sie der Timeout-Einstellung der Lambda-Funktion Zeit hinzu.
Lösung
Protokollieren Sie die API-Aufrufe des AWS-SDK
Verwenden Sie Amazon CloudWatch Logs, um Details über fehlgeschlagene Verbindungen und die Anzahl der jeweils versuchten Wiederholungsversuche abzurufen. Weitere Informationen finden Sie unter Zugreifen auf Amazon CloudWatch-Protokolle für AWS Lambda. Oder sehen Sie sich die folgenden Anweisungen für das AWS-SDK an, das Sie verwenden:
- AWS Lambda-Funktionsprotokollierung in Python
- Protokollieren von AWS SDK für JavaScript-Aufrufe
- Protokollieren von AWS-SDK für Java-Aufrufe
- Protokollieren mit dem AWS-SDK für.NET
- Protokollieren von Serviceaufrufen (AWS SDK für Go)
Beispiel für ein Fehlerprotokoll, in dem der API-Aufruf keine Verbindung herstellen konnte (Verbindungs-Timeout)
START RequestId: b81e56a9-90e0-11e8-bfa8-b9f44c99e76d Version: $LATEST 2018-07-26T14:32:27.393Z b81e56a9-90e0-11e8-bfa8-b9f44c99e76d [AWS ec2 undefined 40.29s 3 retries] describeInstances({}) 2018-07-26T14:32:27.393Z b81e56a9-90e0-11e8-bfa8-b9f44c99e76d { TimeoutError: Socket timed out without establishing a connection ...
Beispiel für ein Fehlerprotokoll, in dem die API-Aufrufverbindung erfolgreich war, aber ein Timeout aufgetreten ist, nachdem die API-Antwort zu lange gedauert hat (Socket-Timeout)
START RequestId: 3c0523f4-9650-11e8-bd98-0df3c5cf9bd8 Version: $LATEST 2018-08-02T12:33:18.958Z 3c0523f4-9650-11e8-bd98-0df3c5cf9bd8 [AWS ec2 undefined 30.596s 3 retries] describeInstances({}) 2018-08-02T12:33:18.978Z 3c0523f4-9650-11e8-bd98-0df3c5cf9bd8 { TimeoutError: Connection timed out after 30s
Hinweis: Diese Protokolle werden nicht generiert, wenn die API-Anfrage innerhalb des Timeouts Ihrer Lambda-Funktion keine Antwort erhält. Wenn die API-Anfrage aufgrund eines Funktions-Timeouts endet, versuchen Sie einen der folgenden Schritte:
- Ändern Sie die Wiederholungseinstellungen im SDK, sodass alle Wiederholungsversuche innerhalb des Timeouts durchgeführt werden.
- Erhöhen Sie die Timeout-Einstellung für die Lambda-Funktion vorübergehend, um genügend Zeit für die Generierung von SDK-Protokollen zu haben.
Ändern Sie die Einstellungen des AWS-SDK
Die Einstellungen für die Anzahl der Wiederholungen und das Timeout des AWS-SDK sollten ausreichend Zeit für Ihren API-Aufruf bieten, um eine Antwort zu erhalten. Um die richtigen Werte für jede Einstellung zu ermitteln, testen Sie verschiedene Konfigurationen und holen Sie sich die folgenden Informationen:
- Durchschnittliche Zeit bis zum Aufbau einer erfolgreichen Verbindung
- Durchschnittliche Zeit, die eine vollständige API-Anfrage benötigt (bis sie erfolgreich zurückgegeben wird)
- Wenn das AWS-SDK oder der AWS-Code Wiederholungsversuche durchführen sollten
Weitere Informationen zum Ändern der Anzahl der Wiederholungen und der Timeout-Einstellungen finden Sie in der folgenden Dokumentation zur Konfiguration des AWS-SDK-Clients:
Im Folgenden finden Sie einige Beispielbefehle, mit denen die Anzahl der Wiederholungsversuche und die Timeout-Einstellungen für jede Laufzeit geändert werden.
Wichtig: Bevor Sie einen der folgenden Befehle verwenden, ersetzen Sie die Beispielwerte für jede Einstellung durch die Werte für Ihren Anwendungsfall.
Beispiel für einen Python-Befehl (Boto 3) zum Ändern der Anzahl der Wiederholungsversuche und der Timeout-Einstellungen
# max_attempts: retry count / read_timeout: socket timeout / connect_timeout: new connection timeout from botocore.session import Session from botocore.config import Config s = Session() c = s.create_client('s3', config=Config(connect_timeout=5, read_timeout=60, retries={'max_attempts': 2}))
Beispielbefehl JavaScript/Node.js zum Ändern der Anzahl der Wiederholungsversuche und der Timeout-Einstellungen
// maxRetries: retry count / timeout: socket timeout / connectTimeout: new connection timeout var AWS = require('aws-sdk'); AWS.config.update({ maxRetries: 2, httpOptions: { timeout: 30000, connectTimeout: 5000 } });
Beispiel für einen Java-Befehl zum Ändern der Anzahl der Wiederholungsversuche und der Timeout-Einstellungen
// setMaxErrorRetry(): retry count / setSocketTimeout(): socket timeout / setConnectionTimeout(): new connection timeout ClientConfiguration clientConfig = new ClientConfiguration(); clientConfig.setSocketTimeout(60000); clientConfig.setConnectionTimeout(5000); clientConfig.setMaxErrorRetry(2); AmazonDynamoDBClient ddb = new AmazonDynamoDBClient(credentialsProvider,clientConfig);
.NET-Beispielbefehl zum Ändern der Anzahl der Wiederholungsversuche und der Timeout-Einstellungen
// MaxErrorRetry: retry count / ReadWriteTimeout: socket timeout / Timeout: new connection timeout var client = new AmazonS3Client( new AmazonS3Config { Timeout = TimeSpan.FromSeconds(5), ReadWriteTimeout = TimeSpan.FromSeconds(60), MaxErrorRetry = 2 });
Beispiel für einen Go-Befehl zum Ändern der Einstellungen für die Anzahl der Wiederholungen
// Create Session with MaxRetry configuration to be shared by multiple service clients. sess := session.Must(session.NewSession(&aws.Config{ MaxRetries: aws.Int(3), })) // Create S3 service client with a specific Region. svc := s3.New(sess, &aws.Config{ Region: aws.String("us-west-2"), })
Beispiel für einen Go-Befehl zum Ändern der Timeout-Einstellungen für Anfragen
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // SQS ReceiveMessage params := &sqs.ReceiveMessageInput{ ... } req, resp := s.ReceiveMessageRequest(params) req.HTTPRequest = req.HTTPRequest.WithContext(ctx) err := req.Send()
(Optional) Ändern Sie die Timeout-Einstellung Ihrer Lambda-Funktion
Ein niedriger Timeout für die Lambda-Funktion kann dazu führen, dass fehlerfreie Verbindungen vorzeitig unterbrochen werden. Wenn dies in Ihrem Anwendungsfall der Fall ist, erhöhen Sie die Timeout-Einstellung für die Funktion, damit Ihr API-Aufruf genügend Zeit hat, eine Antwort zu erhalten.
Verwenden Sie die folgende Formel, um die für den Funktions-Timeout benötigte Basiszeit abzuschätzen:
First attempt (connection timeout + socket timeout) + Number of retries x (connection timeout + socket timeout) + 20 seconds additional code runtime margin = Required Lambda function timeout
Beispiel für eine Timeout-Berechnung für eine Lambda-Funktion
Hinweis: Die folgende Berechnung bezieht sich auf ein AWS-SDK, das für drei Wiederholungsversuche, ein 10-Sekunden-Verbindungs-Timeout und ein 30-Sekunden-Socket-Timeout konfiguriert ist.
First attempt (10 seconds + 30 seconds) + Number of retries [3 * (10 seconds + 30 seconds)] + 20 seconds additional code runtime margin = 180 seconds
Ähnliche Informationen
Invoke (Lambda-API-Referenz)
Fehlerbehandlung und automatische Wiederholungen in AWS Lambda
Relevanter Inhalt
- AWS OFFICIALAktualisiert vor 2 Jahren
- AWS OFFICIALAktualisiert vor 2 Jahren
- AWS OFFICIALAktualisiert vor 2 Jahren
- AWS OFFICIALAktualisiert vor 2 Jahren