Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.
Se vuelve a intentar en AWS SDK para Kotlin
Las llamadas devuelven Servicios de AWS ocasionalmente excepciones inesperadas. Algunos tipos de errores, como los errores transitorios o de limitación, pueden producirse correctamente si se vuelve a intentar realizar la llamada.
En esta página, se describe cómo AWS SDK para Kotlin gestiona los reintentos automáticamente y cómo personalizar el comportamiento de los reintentos para las aplicaciones.
Comprender el comportamiento de los reintentos
En las siguientes secciones se explica cómo el SDK determina cuándo reintentar las solicitudes y qué excepciones se consideran reintentables.
Configuración de reintentos predeterminada
De forma predeterminada, cada cliente de servicio se configura automáticamente con una estrategia de reintentos estándar. La configuración predeterminada intenta realizar una llamada que falla hasta tres veces (el intento inicial más dos reintentos). El retardo intermedio entre cada llamada se configura con un retardo exponencial y una fluctuación aleatoria para evitar tormentas de reintentos. Esta configuración funciona en la mayoría de los casos de uso, pero puede no ser adecuada en algunas circunstancias, como en los sistemas de alto rendimiento.
El SDK solo intenta volver a intentarlo cuando hay errores que se puedan volver a intentar. Algunos ejemplos de errores que se pueden volver a intentar son los tiempos de espera de los sockets, la limitación del lado del servicio, los fallos de bloqueo simultáneos o optimistas y los errores de servicio transitorios. Los parámetros faltantes o no válidos, los authentication/security errores y las excepciones de mala configuración no se consideran reintentables.
Puede personalizar la estrategia de reintentos estándar estableciendo el número máximo de intentos, los retrasos y los retrasos, así como la configuración del conjunto de fichas.
¿Qué excepciones se pueden volver a intentar?
AWS SDK para Kotlin Utiliza una política de reintentos preconfigurada que determina qué excepciones se pueden volver a intentar. La configuración del cliente de servicio tiene una retryPolicy propiedad que especifica la política que se aplica a los reintentos. Si no se especifica ningún valor personalizado, el valor predeterminado es AwsRetryPolicy.
Se determina que las siguientes excepciones se pueden volver a intentar mediante: AwsRetryPolicy
Se puede volver a intentar mediante código de error
Cualquiera ServiceException con uno de los siguientes valoressdkErrorMetadata.errorCode:
BandwidthLimitExceededEC2ThrottledExceptionIDPCommunicationErrorLimitExceededExceptionPriorRequestNotCompleteProvisionedThroughputExceededExceptionRequestLimitExceededRequestThrottledRequestThrottledExceptionRequestTimeoutRequestTimeoutExceptionSlowDownThrottledExceptionThrottlingThrottlingExceptionTooManyRequestsExceptionTransactionInProgressException
Se puede volver a intentar mediante el código de estado HTTP
Cualquiera ServiceException con uno de los siguientes valoressdkErrorMetadata.statusCode:
500 (error de servicio interno)
502 (puerta de enlace defectuosa)
503 (servicio no disponible)
504 (tiempo de espera de la puerta de enlace)
Se puede volver a intentar por tipo de error
Cualquiera ServiceException con uno de los siguientes valoressdkErrorMetadata.errorType:
ErrorType.Server(como errores de servicio interno)ErrorType.Client(como una solicitud no válida, un recurso no encontrado, acceso denegado, etc.)
Se puede volver a intentar mediante metadatos del SDK
En cualquier lugarSdkBaseException:
sdkErrorMetadata.isRetryableestrue(como un tiempo de espera del lado del cliente, un networking/socket error, etc.)sdkErrorMetadata.isThrottlingestrue(por ejemplo, hacer demasiadas solicitudes en poco tiempo)
Para obtener una lista completa de las excepciones que puede introducir cada cliente de servicio, consulta la documentación de referencia de la API específica del servicio.
Comprueba si una excepción se puede volver a intentar
Para determinar si el SDK considera que una excepción se puede volver a intentar, comprueba la propiedad de las excepciones detectadas: isRetryable
try { dynamoDbClient.putItem { tableName = "MyTable" item = mapOf("id" to AttributeValue.S("123")) } } catch (e: SdkBaseException) { println("Exception occurred: ${e.message}") if (e.sdkErrorMetadata.isRetryable) { println("This exception is retryable - SDK will automatically retry") println("If you're seeing this, retries may have been exhausted") } else { println("This exception is not retryable - fix the underlying issue") // Common non-retryable scenarios. when { e.message?.contains("ValidationException") == true -> println("Check your request parameters") e.message?.contains("AccessDenied") == true -> println("Check your IAM permissions") e.message?.contains("ResourceNotFound") == true -> println("Verify the resource exists") } } }
¿Qué excepciones llegan a tu código cuando los reintentos fallan?
Cuando el mecanismo de reintento del SDK no puede resolver un problema, se añaden excepciones al código de la aplicación. Comprender estos tipos de excepciones te ayuda a implementar una gestión de errores adecuada. Estas no son las excepciones que desencadenan las recuperaciones, sino que las gestiona internamente el SDK.
Su código detectará los siguientes tipos de excepciones cuando se agoten o deshabiliten los reintentos:
- Excepciones de servicio tras el agotamiento de los reintentos
-
Cuando todos los reintentos fallan, el código detecta la última excepción de servicio (subclase de
AwsServiceException) que provocó el error del último reintento. Podría tratarse de un error de limitación, un error del servidor u otra excepción específica del servicio que el SDK no pudo resolver mediante reintentos. - Excepciones de red tras agotarse los reintentos
-
Cuando los problemas de red persisten tras todos los intentos, el código detecta las
ClientExceptioninstancias para detectar problemas como los tiempos de espera de la conexión, los fallos de resolución del DNS y otros problemas de conectividad que el SDK no ha podido resolver.
Usa el siguiente patrón para gestionar estas excepciones en tu aplicación:
try { s3Client.getObject { bucket = "amzn-s3-demo-bucket" key = "my-key" } } catch (e: AwsServiceException) { // Service-side errors that persisted through all retries. println("Service error after retries: ${e.errorDetails?.errorCode} - ${e.message}") // Handle specific service errors that couldn't be resolved. if (e.errorDetails?.errorCode == "ServiceQuotaExceededException" || e.errorDetails?.errorCode == "ThrottlingException") { println("Rate limiting persisted - consider longer delays or quota increase") } } catch (e: ClientException) { // Client-side errors (persistent network issues, DNS resolution failures, etc.) println("Client error after retries: ${e.message}") }
Personalización del comportamiento de los reintentos
En las siguientes secciones, se muestra cómo personalizar el comportamiento de reintentos del SDK para cada caso de uso específico.
Configura el número máximo de intentos
Puede personalizar el número máximo de intentos predeterminado (3) en el bloque retryStrategy DSL durante la construcción del cliente.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { maxAttempts = 5 } }
Con el cliente del servicio DynamoDB mostrado en el fragmento anterior, el SDK intenta realizar llamadas a la API que fallan hasta cinco veces (el intento inicial más cuatro reintentos).
Para deshabilitar completamente los reintentos automáticos, establezca el número máximo de intentos en uno, como se muestra en el siguiente fragmento.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { maxAttempts = 1 // The SDK makes no retries. } }
Configure los retrasos y los retrasos
Si es necesario volver a intentarlo, la estrategia de reintento predeterminada espera antes de realizar el siguiente intento. El retraso del primer reintento es pequeño, pero aumenta exponencialmente en los reintentos posteriores. La cantidad máxima de retraso está limitada para que no aumente demasiado.
Por último, se aplica una fluctuación aleatoria a los retrasos entre todos los intentos. La fluctuación ayuda a mitigar el efecto de las grandes flotas, que pueden provocar tormentas que vuelvan a intentarlo. (Consulte esta entrada del blog de AWS arquitectura
Los parámetros de retardo se pueden configurar en el bloque DSLdelayProvider.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { delayProvider { initialDelay = 100.milliseconds maxBackoff = 5.seconds } } }
Con la configuración que se muestra en el fragmento anterior, el cliente retrasa el primer intento hasta 100 milisegundos. El tiempo máximo entre un reintento es de 5 segundos.
Están disponibles los siguientes parámetros para los retrasos y el retardo del ajuste.
| Parámetro | Valor predeterminado | Descripción |
|---|---|---|
initialDelay |
10 milisegundos | La cantidad máxima de retraso para el primer reintento. Cuando se aplica una fluctuación de fase, la cantidad real de retraso puede ser menor. |
jitter |
1.0 (fluctuación total) |
La amplitud máxima con la que se puede reducir aleatoriamente el retraso calculado. El valor predeterminado de 1,0 significa que el retraso calculado se puede reducir hasta un 100% (por ejemplo, hasta 0). Un valor de 0,5 significa que el retraso calculado se puede reducir hasta la mitad. Por lo tanto, un retraso máximo de 10 ms podría reducirse a entre 5 y 10 ms. Un valor de 0.0 significa que no se aplica ninguna fluctuación. importante️ La configuración de fluctuación es una función avanzada. Por lo general, no se recomienda personalizar este comportamiento. |
maxBackoff |
20 segundos | La cantidad máxima de demora que se puede aplicar a cualquier intento. Si se establece este valor, se limita el crecimiento exponencial que se produce entre los intentos posteriores y se evita que el máximo calculado sea demasiado grande. Este parámetro limita el retraso calculado antes de que se aplique la fluctuación de fase. Si se aplica, la fluctuación podría reducir aún más el retraso. |
scaleFactor |
1.5 | La base exponencial a partir de la cual se incrementarán los retardos máximos subsiguientes. Por ejemplo, si uno es
|
Configure el depósito de fichas de reintento
Puede modificar aún más el comportamiento de la estrategia de reintentos estándar ajustando la configuración predeterminada del depósito de fichas. El conjunto de fichas de reintentos ayuda a reducir los reintentos que tienen menos probabilidades de éxito o que pueden tardar más tiempo en resolverse, como los errores de tiempo de espera o de aceleración.
importante
La configuración del depósito de fichas es una función avanzada. Por lo general, no se recomienda personalizar este comportamiento.
Cada reintento (incluido opcionalmente el intento inicial) reduce parte de la capacidad del depósito de fichas. La cantidad disminuida depende del tipo de intento. Por ejemplo, volver a intentar los errores transitorios puede resultar económico, pero volver a intentarlo cuando se agota el tiempo de espera o se reduce el tiempo de espera puede resultar más caro.
Si el intento se realiza correctamente, se devuelve la capacidad al depósito. El depósito no puede incrementarse más allá de su capacidad máxima ni reducirse por debajo de cero.
Según el valor de la useCircuitBreakerMode configuración, los intentos de reducir la capacidad por debajo de cero dan como resultado uno de los siguientes resultados:
-
Si la configuración es TRUE, se produce una excepción: por ejemplo, si se han realizado demasiados reintentos y es poco probable que se realicen más reintentos.
-
Si el valor es FALSO, se produce un retraso, por ejemplo, hasta que el depósito vuelva a tener suficiente capacidad.
nota
Cuando se activa el disyuntor (el depósito de fichas alcanza su capacidad cero), el SDK muestra un mensaje ClientException con el mensaje «Se ha superado la capacidad de reintento». Se trata de una excepción del lado del cliente, no de una excepciónAwsServiceException, porque se origina en la lógica de reintentos del SDK y no en el servicio. AWS La excepción se produce inmediatamente sin intentar realizar la operación, lo que ayuda a evitar que se repitan los intentos durante las interrupciones del servicio.
Los parámetros del depósito de fichas se pueden configurar en el bloque tokenBucketDSL:
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { tokenBucket { maxCapacity = 100 refillUnitsPerSecond = 2 } } }
Están disponibles los siguientes parámetros para ajustar el grupo de reintentos:
| Parámetro | Valor predeterminado | Descripción |
|---|---|---|
initialTryCost |
0 | La cantidad que se va a reducir con respecto a la cubeta en los intentos iniciales. El valor predeterminado de 0 significa que no se reducirá la capacidad y, por lo tanto, los intentos iniciales no se detendrán ni retrasarán. |
initialTrySuccessIncrement |
1 | La cantidad necesaria para incrementar la capacidad cuando el intento inicial se realizó correctamente. |
maxCapacity |
500 | La capacidad máxima del depósito de fichas. El número de fichas disponibles no puede superar este número. |
refillUnitsPerSecond |
0 | La cantidad de capacidad que se vuelve a añadir al depósito cada segundo. Un valor de 0 significa que no se vuelve a añadir capacidad automáticamente. (Por ejemplo, solo los intentos exitosos dan como resultado un aumento de la capacidad). Un valor de 0 debe useCircuitBreakerMode ser VERDADERO. |
retryCost |
5 | La cantidad que se debe reducir de la cubeta en caso de un intento tras un error transitorio. La misma cantidad se vuelve a acumular en el depósito si el intento tiene éxito. |
timeoutRetryCost |
10 | La cantidad que se deduce de la cubeta para un intento tras un fallo en el tiempo de espera o en la aceleración. La misma cantidad se vuelve a acumular en el depósito si el intento tiene éxito. |
useCircuitBreakerMode |
TRUE | Determina el comportamiento en caso de que un intento de reducir la capacidad del depósito caiga por debajo de cero. Si el valor es TRUE, el depósito de fichas generará una excepción que indicará que no existe más capacidad de reintentos. Si el valor es FALSO, el depósito de fichas retrasará el intento hasta que se haya rellenado la capacidad suficiente. |
Para obtener información detallada sobre los tipos de excepciones que se producen durante los escenarios de reintento, incluidas las excepciones a los disyuntores, consulte. ¿Qué excepciones llegan a tu código cuando los reintentos fallan?
Configure los reintentos adaptativos
Como alternativa a la estrategia de reintentos estándar, la estrategia de reintentos adaptativa es un enfoque avanzado que busca la tasa de solicitudes ideal para minimizar los errores de limitación.
importante
Los reintentos adaptativos son un modo de reintento avanzado. Por lo general, no se recomienda utilizar esta estrategia de reintentos.
Los reintentos adaptables incluyen todas las características de los reintentos estándar. Añade un limitador de velocidad en el lado del cliente que mide la tasa de solicitudes restringidas en comparación con las solicitudes no restringidas. También limita el tráfico para intentar mantenerse dentro de un ancho de banda seguro, lo que idealmente no provoca errores de limitación.
La velocidad se adapta en tiempo real a los cambios en las condiciones del servicio y los patrones de tráfico y, en consecuencia, podría aumentar o disminuir la velocidad del tráfico. Lo que es más grave, el limitador de velocidad podría retrasar los intentos iniciales en situaciones de alto tráfico.
La estrategia de reintento adaptativo se selecciona proporcionando un parámetro adicional al método. retryStrategy Los parámetros del limitador de velocidad se pueden configurar en el bloque rateLimiterDSL.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy(AdaptiveRetryStrategy) { maxAttempts = 10 rateLimiter { minFillRate = 1.0 smoothing = 0.75 } } }
nota
La estrategia de reintento adaptativo supone que el cliente trabaja con un único recurso (por ejemplo, una tabla de DynamoDB o un bucket de Amazon S3).
Si utiliza un solo cliente para varios recursos, la limitación o las interrupciones asociadas a un recurso provocan un aumento de la latencia y errores cuando el cliente accede a todos los demás recursos. Cuando utilice la estrategia de reintento adaptativo, le recomendamos que utilice un único cliente para cada recurso.