Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.
Réessaie dans AWS SDK pour Kotlin
Appels renvoyant de Services AWS temps en temps des exceptions inattendues. Certains types d'erreurs, tels que les erreurs de régulation ou les erreurs transitoires, peuvent réussir si l'appel est relancé.
Cette page décrit comment le gestionnaire AWS SDK pour Kotlin gère automatiquement les nouvelles tentatives et comment personnaliser le comportement des nouvelles tentatives pour vos applications.
Comprendre le comportement des nouvelles tentatives
Les sections suivantes expliquent comment le SDK détermine à quel moment les demandes doivent être réessayées et quelles exceptions sont considérées comme réessayables.
Configuration de nouvelle tentative par défaut
Par défaut, chaque client de service est automatiquement configuré avec une stratégie de nouvelle tentative standard. La configuration par défaut essaie un appel qui échoue jusqu'à trois fois (la première tentative plus deux tentatives). Le délai entre chaque appel est configuré avec un recul exponentiel et une instabilité aléatoire afin d'éviter les tempêtes de nouvelles tentatives. Cette configuration fonctionne dans la majorité des cas d'utilisation, mais peut s'avérer inappropriée dans certaines circonstances, comme dans le cas des systèmes à haut débit.
Le SDK tente de réessayer uniquement en cas d'erreur réessayable. Parmi les erreurs réessayables, citons les délais d'expiration des sockets, le ralentissement côté service, la simultanéité ou les échecs de verrouillage optimistes, ainsi que les erreurs de service transitoires. Les paramètres manquants ou non valides, les authentication/security erreurs et les exceptions de mauvaise configuration ne sont pas considérés comme réessayables.
Vous pouvez personnaliser la stratégie de réessai standard en définissant le nombre maximal de tentatives, de délais et d'interruptions, ainsi que la configuration du bucket de jetons.
Quelles exceptions sont réessayables ?
AWS SDK pour Kotlin Utilise une politique de nouvelle tentative préconfigurée qui détermine quelles exceptions peuvent être réessayées. La configuration du client de service possède une retryPolicy
propriété qui spécifie la politique appliquée aux nouvelles tentatives. Si aucune valeur personnalisée n'est spécifiée, la valeur par défaut est AwsRetryPolicy.
Les exceptions suivantes sont considérées comme réessayables par : AwsRetryPolicy
Réessayable par code d'erreur
N'importe ServiceException
lequel avec un sdkErrorMetadata.errorCode
des éléments suivants :
BandwidthLimitExceeded
EC2ThrottledException
IDPCommunicationError
LimitExceededException
PriorRequestNotComplete
ProvisionedThroughputExceededException
RequestLimitExceeded
RequestThrottled
RequestThrottledException
RequestTimeout
RequestTimeoutException
SlowDown
ThrottledException
Throttling
ThrottlingException
TooManyRequestsException
TransactionInProgressException
Réessayable par code d'état HTTP
N'importe ServiceException
lequel avec un sdkErrorMetadata.statusCode
des éléments suivants :
500 (erreur de service interne)
502 (Mauvaise passerelle)
503 (Service non disponible)
504 (délai d'expiration de la passerelle)
Réessayable par type d'erreur
N'importe ServiceException
lequel avec un sdkErrorMetadata.errorType
des éléments suivants :
ErrorType.Server
(telles que des erreurs de service internes)ErrorType.Client
(comme une demande non valide, une ressource introuvable, un accès refusé, etc.)
Réessayable à l'aide des métadonnées du SDK
N'importe SdkBaseException
où :
sdkErrorMetadata.isRetryable
esttrue
(tel qu'un délai d'attente côté client, une networking/socket erreur, etc.)sdkErrorMetadata.isThrottling
esttrue
(par exemple, faire trop de demandes en peu de temps)
Pour obtenir la liste complète des exceptions pouvant être émises par chaque client de service, consultez la documentation de référence des API spécifiques au service.
Vérifiez si une exception est réessayable
Pour déterminer si le SDK considère qu'une exception peut être réessayée, vérifiez la isRetryable
propriété des exceptions détectées :
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") } } }
Quelles exceptions atteignent votre code lorsque les nouvelles tentatives échouent
Lorsque le mécanisme de nouvelle tentative du SDK ne permet pas de résoudre un problème, des exceptions sont apportées au code de votre application. La compréhension de ces types d'exceptions vous permet de mettre en œuvre une gestion appropriée des erreurs. Ce ne sont pas ces exceptions qui déclenchent les récupérations : elles sont gérées en interne par le SDK.
Votre code détectera les types d'exceptions suivants lorsque les nouvelles tentatives seront épuisées ou désactivées :
- Exceptions de service après l'épuisement des nouvelles tentatives
-
Lorsque toutes les tentatives échouent, votre code détecte la dernière exception de service (sous-classe de
AwsServiceException
) à l'origine de l'échec de la dernière tentative. Il peut s'agir d'une erreur de régulation, d'une erreur de serveur ou d'une autre exception spécifique au service que le SDK n'a pas pu résoudre par de nouvelles tentatives. - Exceptions réseau après épuisement des nouvelles tentatives
-
Lorsque les problèmes réseau persistent malgré toutes les tentatives, votre code détecte les
ClientException
instances pour détecter des problèmes tels que des délais de connexion, des échecs de résolution DNS ou d'autres problèmes de connectivité que le SDK n'a pas pu résoudre.
Utilisez le modèle suivant pour gérer ces exceptions dans votre application :
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}") }
Personnalisation du comportement des nouvelles tentatives
Les sections suivantes montrent comment personnaliser le comportement de nouvelle tentative du SDK en fonction de votre cas d'utilisation spécifique.
Configurer le nombre maximal de tentatives
Vous pouvez personnaliser le nombre maximal de tentatives par défaut (3) dans le bloc retryStrategy
DSL lors de la construction du client.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { maxAttempts = 5 } }
Avec le client de service DynamoDB illustré dans l'extrait précédent, le SDK essaie les appels d'API qui échouent jusqu'à cinq fois (la première tentative plus quatre nouvelles tentatives).
Vous pouvez désactiver complètement les tentatives automatiques en fixant le nombre maximum de tentatives à une, comme indiqué dans l'extrait suivant.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { maxAttempts = 1 // The SDK makes no retries. } }
Configurer les délais et les retards
Si une nouvelle tentative est nécessaire, la stratégie de nouvelle tentative par défaut attend avant d'effectuer la prochaine tentative. Le délai de la première tentative est faible, mais il augmente de façon exponentielle lors des tentatives ultérieures. Le délai maximal est plafonné afin qu'il ne devienne pas trop important.
Enfin, une instabilité aléatoire est appliquée aux délais entre toutes les tentatives. L'instabilité contribue à atténuer les effets des grandes flottes qui peuvent provoquer des tempêtes de nouvelles tentatives. (Consultez ce billet de blog sur AWS l'architecture
Les paramètres de délai sont configurables dans le bloc delayProvider
DSL.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { delayProvider { initialDelay = 100.milliseconds maxBackoff = 5.seconds } } }
Avec la configuration présentée dans l'extrait précédent, le client retarde la première tentative jusqu'à 100 millisecondes. Le délai maximum entre chaque nouvelle tentative est de 5 secondes.
Les paramètres suivants sont disponibles pour le réglage des délais et du ralentissement.
Paramètre | Valeur par défaut | Description |
---|---|---|
initialDelay |
10 millisecondes | Délai maximal pour la première tentative. Lorsque de la gigue est appliquée, le délai réel peut être moindre. |
jitter |
1,0 (gigue complète) |
Amplitude maximale permettant de réduire de manière aléatoire le délai calculé. La valeur par défaut de 1,0 signifie que le délai calculé peut être réduit à n'importe quel montant jusqu'à 100 % (par exemple, jusqu'à 0). Une valeur de 0,5 signifie que le délai calculé peut être réduit de moitié au maximum. Ainsi, un délai maximum de 10 ms pourrait être réduit à une valeur comprise entre 5 ms et 10 ms. Une valeur de 0,0 signifie qu'aucune instabilité n'est appliquée. Important️ La configuration Jitter est une fonctionnalité avancée. La personnalisation de ce comportement n'est généralement pas recommandée. |
maxBackoff |
20 secondes | Le délai maximal à appliquer à toute tentative. La définition de cette valeur limite la croissance exponentielle qui se produit entre les tentatives suivantes et évite que le maximum calculé ne soit trop élevé. Ce paramètre limite le délai calculé avant l'application de la gigue. Si elle est appliquée, la gigue peut encore réduire le délai. |
scaleFactor |
1.5 | Base exponentielle selon laquelle les délais maximaux ultérieurs seront augmentés. Par exemple, étant donné un an
|
Configurer le bucket de jetons Retry
Vous pouvez modifier davantage le comportement de la stratégie de nouvelle tentative standard en ajustant la configuration du bucket de jetons par défaut. Le bucket de jetons de nouvelle tentative permet de réduire le nombre de tentatives qui ont moins de chances de réussir ou dont la résolution peut prendre plus de temps, telles que les échecs liés au délai imparti ou à la limitation des délais.
Important
La configuration du bucket à jetons est une fonctionnalité avancée. La personnalisation de ce comportement n'est généralement pas recommandée.
Chaque nouvelle tentative (y compris éventuellement la tentative initiale) réduit une partie de la capacité du bucket de jetons. Le montant décrémenté dépend du type de tentative. Par exemple, il peut être peu coûteux de réessayer des erreurs transitoires, mais une nouvelle tentative d'expiration ou de limitation des erreurs peut s'avérer plus coûteuse.
Une tentative réussie rétablit la capacité du compartiment. Le godet ne doit pas être incrémenté au-delà de sa capacité maximale ni décrémenté en dessous de zéro.
En fonction de la valeur du useCircuitBreakerMode
paramètre, les tentatives de réduction de la capacité en dessous de zéro entraînent l'un des résultats suivants :
-
Si le paramètre est VRAI, une exception est déclenchée. Par exemple, si trop de tentatives ont eu lieu et qu'il est peu probable que d'autres tentatives aboutissent.
-
Si le paramètre est FALSE, il y a un délai, par exemple, jusqu'à ce que le compartiment ait de nouveau une capacité suffisante.
Note
Lorsque le disjoncteur s'active (la capacité du compartiment à jetons atteint zéro), le SDK émet un message ClientException
avec le message « Capacité de réessai dépassée ». Il s'agit d'une exception côté client, et non d'une exceptionAwsServiceException
, car elle provient de la logique de nouvelle tentative du SDK plutôt que du service. AWS L'exception est déclenchée immédiatement sans tentative d'opération, ce qui permet d'éviter de nouvelles tentatives en cas de panne de service.
Les paramètres du bucket de jetons sont configurables dans le bloc tokenBucket
DSL :
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy { tokenBucket { maxCapacity = 100 refillUnitsPerSecond = 2 } } }
Les paramètres suivants sont disponibles pour régler le bucket de jetons Retry :
Paramètre | Valeur par défaut | Description |
---|---|---|
initialTryCost |
0 | Le montant à déduire du bucket lors des premières tentatives. La valeur par défaut de 0 signifie qu'aucune capacité ne sera décrémentée et que les tentatives initiales ne seront donc ni interrompues ni retardées. |
initialTrySuccessIncrement |
1 | Le montant à augmenter lorsque la première tentative a été couronnée de succès. |
maxCapacity |
500 | Capacité maximale du bucket de jetons. Le nombre de jetons disponibles ne peut pas dépasser ce nombre. |
refillUnitsPerSecond |
0 | Quantité de capacité ajoutée à nouveau au godet chaque seconde. Une valeur de 0 signifie qu'aucune capacité n'est automatiquement ajoutée à nouveau. (Par exemple, seules les tentatives réussies permettent d'augmenter la capacité). Une valeur de 0 useCircuitBreakerMode doit être vraie. |
retryCost |
5 | Le montant à déduire du compartiment en cas de tentative consécutive à un échec temporaire. Le même montant est réincrémenté dans le compartiment si la tentative est réussie. |
timeoutRetryCost |
10 | Le montant à déduire du compartiment en cas de tentative consécutive à un délai d'expiration ou à une défaillance de la régulation. Le même montant est réincrémenté dans le compartiment si la tentative est réussie. |
useCircuitBreakerMode |
TRUE | Détermine le comportement lorsqu'une tentative de réduction de la capacité entraîne une chute de la capacité du compartiment en dessous de zéro. Lorsque la valeur est TRUE, le bucket de jetons génère une exception indiquant qu'il n'existe plus de capacité de nouvelle tentative. Lorsque la valeur est FALSE, le bucket de jetons retarde la tentative jusqu'à ce que la capacité soit suffisante. |
Pour des informations détaillées sur les types d'exceptions déclenchés lors de scénarios de nouvelle tentative, y compris les exceptions relatives aux disjoncteurs, consultezQuelles exceptions atteignent votre code lorsque les nouvelles tentatives échouent.
Configuration de nouvelles tentatives adaptatives
Comme alternative à la stratégie de nouvelle tentative standard, la stratégie de nouvelle tentative adaptative est une approche avancée qui recherche le taux de demandes idéal afin de minimiser les erreurs de limitation.
Important
Les tentatives adaptatives sont un mode de nouvelle tentative avancé. L'utilisation de cette stratégie de nouvelle tentative n'est généralement pas recommandée.
Les tentatives adaptatives incluent toutes les fonctionnalités des tentatives standard. Il ajoute un limiteur de débit côté client qui mesure le taux de demandes limitées par rapport aux demandes non limitées. Cela limite également le trafic pour tenter de rester dans une bande passante sûre, ce qui ne provoque idéalement aucune erreur de régulation.
Le tarif s'adapte en temps réel à l'évolution des conditions de service et des modèles de trafic et peut augmenter ou diminuer le taux de trafic en conséquence. Surtout, le limiteur de débit peut retarder les premières tentatives dans les scénarios à fort trafic.
Vous sélectionnez la stratégie de nouvelle tentative adaptative en fournissant un paramètre supplémentaire à la retryStrategy
méthode. Les paramètres du limiteur de débit sont configurables dans le bloc rateLimiter
DSL.
val dynamoDb = DynamoDbClient.fromEnvironment { retryStrategy(AdaptiveRetryStrategy) { maxAttempts = 10 rateLimiter { minFillRate = 1.0 smoothing = 0.75 } } }
Note
La stratégie de nouvelle tentative adaptative suppose que le client travaille sur une seule ressource (par exemple, une table DynamoDB ou un compartiment Amazon S3).
Si vous utilisez un seul client pour plusieurs ressources, les ralentissements ou les pannes associés à une ressource entraînent une latence accrue et des défaillances lorsque le client accède à toutes les autres ressources. Lorsque vous utilisez la stratégie de nouvelle tentative adaptative, nous vous recommandons d'utiliser un seul client pour chaque ressource.