¿Cómo soluciono los problemas de reintento y tiempo de espera al invocar una función de Lambda mediante un AWS SDK?
Cuando invoco mi función de AWS Lambda mediante un AWS SDK, se agota el tiempo de espera de la función, la solicitud de la API deja de responder o se duplica una acción de la API. ¿Cómo soluciono estos problemas?
Breve descripción
Hay tres motivos por los que se producen problemas de reintento y de tiempo de espera al invocar una función de Lambda con un AWS SDK:
- No se puede acceder a una API remota o tarda demasiado en responder a una llamada a la API.
- La llamada a la API no recibe respuesta dentro del tiempo de espera del socket.
- La llamada a la API no recibe respuesta dentro del periodo de tiempo de espera de la función de Lambda.
Nota: Las llamadas a la API pueden tardar más de lo esperado cuando se producen problemas de conexión a la red. Los problemas de red también pueden provocar reintentos y solicitudes de API duplicadas. Para prepararse para estos casos, asegúrese de que la función de Lambda sea idempotente.
Si realiza una llamada a la API con un AWS SDK y la llamada falla, AWS SDK vuelve a intentar realizar la llamada automáticamente. La cantidad de veces que AWS SDK reintenta las llamadas y durante cuánto tiempo depende de la configuración, que varía de un AWS SDK a otro.
Configuración de reintento predeterminada de AWS SDK
Nota: Algunos valores pueden ser diferentes para otros servicios de AWS.
AWS SDK | Número máximo de reintentos | Tiempo de espera de conexión | Tiempo de espera del socket |
Python (Boto 3) | En función del servicio | 60 segundos | 60 segundos |
JavaScript/Node.js | En función del servicio | N/D | 120 segundos |
Java | 3 | 10 segundos | 50 segundos |
.NET | 4 | 100 segundos | 300 segundos |
Go | 3 | N/D | N/D |
Para solucionar los problemas de reintento y tiempo de espera, primero revise los registros de la llamada a la API para localizar el problema. A continuación, cambie la configuración del número de reintentos y el tiempo de espera de AWS SDK según sea necesario en cada caso. Para dejar suficiente tiempo para responder a la llamada a la API, añada un tiempo a la configuración del tiempo de espera de la función de Lambda.
Resolución
Registro de las llamadas a la API realizadas por AWS SDK
Utilice los Registros de Amazon CloudWatch para obtener detalles sobre las conexiones fallidas y el número de reintentos para cada una de ellas. Para obtener más información, consulte Acceso a los registros de Amazon CloudWatch para AWS Lambda. También puede consultar las siguientes instrucciones para el AWS SDK que esté utilizando:
- Registro de funciones de AWS Lambda en Python
- Registro de llamadas de AWS SDK para JavaScript
- Registro de llamadas de AWS SDK para Java
- Registro con AWS SDK para .NET
- Registro de llamadas de servicio (AWS SDK para Go)
Ejemplo de registro de errores en el que la llamada a la API no pudo establecer una conexión (tiempo de espera de conexión)
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 ...
Ejemplo de registro de errores en el que la conexión a la llamada a la API se realizó correctamente, pero se agotó el tiempo de espera después de que la respuesta a la API tardara demasiado (tiempo de espera del socket)
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
Nota: Estos registros no se generan si la solicitud de la API no recibe una respuesta dentro del tiempo de espera de la función de Lambda. Si la solicitud de la API finaliza debido a que se ha agotado el tiempo de espera de una función, pruebe una de las siguientes opciones:
- Cambie la configuración de reintentos en SDK para que todos los reintentos se realicen dentro del tiempo de espera.
- Aumente temporalmente la configuración del tiempo de espera de la función de Lambda con el fin de tener tiempo suficiente para generar los registros de SDK.
Cambio de la configuración de AWS SDK
La configuración del número de reintentos y el tiempo de espera de AWS SDK deberían permitir tiempo suficiente para que la llamada a la API reciba una respuesta. Para determinar los valores correctos para cada ajuste, pruebe diferentes configuraciones y obtenga la siguiente información:
- Tiempo promedio para establecer una conexión satisfactoria
- Tiempo promedio que tarda una solicitud de API completa (hasta que se devuelva correctamente)
- Si los reintentos deben realizarse mediante SDK AWS o código
Para obtener más información sobre cómo cambiar la configuración del número de reintentos y el tiempo de espera, consulte la siguiente documentación sobre configuración del cliente AWS SDK:
A continuación se muestran algunos comandos de ejemplo que cambian la configuración del número de reintentos y el tiempo de espera para cada tiempo de ejecución.
Importante: Antes de usar cualquiera de los siguientes comandos, sustituya los valores de ejemplo de cada configuración por los valores de su caso.
Ejemplo de comando de Python (Boto 3) para cambiar la configuración del número de reintentos y el tiempo de espera
# 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}))
Ejemplo de comando de JavaScript/Node.js para cambiar la configuración del número de reintentos y el tiempo de espera
// 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 } });
Ejemplo de comando de Java para cambiar la configuración del número de reintentos y el tiempo de espera
// 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);
Ejemplo de comando de .NET para cambiar la configuración del número de reintentos y el tiempo de espera
// 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 });
Ejemplo de comando de Go para cambiar la configuración del número de reintentos
// 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"), })
Ejemplo de comando de Go para cambiar la configuración del tiempo de espera de la solicitud
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()
(Opcional) Cambio de la configuración de tiempo de espera de la función de Lambda
Un tiempo de espera bajo de la función de Lambda puede provocar que las conexiones en buen estado se interrumpan antes de tiempo. Si esto ocurre en su caso, aumente el ajuste del tiempo de espera de la función con el fin de que su llamada a la API tenga tiempo suficiente para obtener una respuesta.
Utilice la siguiente fórmula para calcular el tiempo de base necesario para el tiempo de espera de la función:
First attempt (connection timeout + socket timeout) + Number of retries x (connection timeout + socket timeout) + 20 seconds additional code runtime margin = Required Lambda function timeout
Ejemplo de cálculo del tiempo de espera de la función de Lambda
Nota: El siguiente cálculo es para un AWS SDK configurado para tres reintentos, un tiempo de espera de conexión de diez segundos y un tiempo de espera del socket de treinta segundos.
First attempt (10 seconds + 30 seconds) + Number of retries [3 * (10 seconds + 30 seconds)] + 20 seconds additional code runtime margin = 180 seconds
Información relacionada
Invoke (referencia de la API de Lambda)
Contenido relevante
- OFICIAL DE AWSActualizada hace un año
- OFICIAL DE AWSActualizada hace un año
- OFICIAL DE AWSActualizada hace un año
- OFICIAL DE AWSActualizada hace 3 años