Wie behebe ich Probleme mit Wiederholungsversuchen und Timeouts, wenn ich eine Lambda-Funktion mithilfe eines AWS-SDK aufrufe?

Lesedauer: 6 Minute
0

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 SDKMaximale Anzahl an WiederholungenVerbindungs-TimeoutSocket-Timeout
Python (Boto 3)hängt vom Service ab60 Sekunden60 Sekunden
JavaScript/Node.jshängt vom Service abN/A120 Sekunden
Java310 Sekunden50 Sekunden
.NET4100 Sekunden300 Sekunden
Go3N/AN/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:

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 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

Lambda-Kontingente

AWS OFFICIAL
AWS OFFICIALAktualisiert vor 2 Jahren