Réessais pour les fonctions durables de Lambda - AWS Lambda

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éessais pour les fonctions durables de Lambda

Les fonctions durables offrent des fonctionnalités de relance automatique qui permettent à vos applications de résister aux défaillances transitoires. Le SDK gère les nouvelles tentatives à deux niveaux : les tentatives par étapes en cas d'échec de la logique métier et les tentatives du backend en cas de défaillance de l'infrastructure.

Étape 2 : Réessaie

Lorsqu'une exception non détectée se produit au cours d'une étape, le SDK réessaie automatiquement l'étape en fonction de la stratégie de nouvelle tentative configurée. Les tentatives d'étape sont des opérations ponctuelles qui permettent au SDK de suspendre l'exécution et de la reprendre ultérieurement sans perdre la progression.

Étape 1 : comportement en cas de nouvelle tentative

Le tableau suivant décrit comment le SDK gère les exceptions par étapes :

Scénario Que se passe-t-il Impact du mesurage
Exception en cours avec les tentatives de nouvelle tentative restantes Le SDK crée un point de contrôle pour la nouvelle tentative et suspend la fonction. Lors de l'appel suivant, l'étape réessaie avec le délai d'attente configuré. 1 opération+erreur sur la taille de la charge utile
Exception en cours, aucune nouvelle tentative n'ayant été tentée L'étape échoue et génère une exception. Si le code de votre gestionnaire ne détecte pas cette exception, l'exécution complète échoue. 1 opération+erreur sur la taille de la charge utile

Lorsqu'une étape doit être réessayée, le SDK vérifie l'état de nouvelle tentative et quitte l'appel Lambda si aucune autre tâche n'est en cours d'exécution. Cela permet au SDK d'implémenter des délais de temporisation sans consommer de ressources informatiques. La fonction reprend automatiquement après la période d'attente.

Configuration des stratégies de nouvelle tentative

Configurez des stratégies de nouvelle tentative pour contrôler la manière dont les étapes gèrent les échecs. Vous pouvez spécifier le nombre maximum de tentatives, les intervalles d'attente et les conditions de réessai.

Retard exponentiel avec un maximum de tentatives :

TypeScript
const result = await context.step('call-api', async () => { const response = await fetch('https://api.example.com/data'); if (!response.ok) throw new Error(`API error: ${response.status}`); return await response.json(); }, { retryStrategy: (error, attemptCount) => { if (attemptCount >= 5) { return { shouldRetry: false }; } // Exponential backoff: 2s, 4s, 8s, 16s, 32s (capped at 300s) const delay = Math.min(2 * Math.pow(2, attemptCount - 1), 300); return { shouldRetry: true, delay: { seconds: delay } }; } });
Python
def retry_strategy(error, attempt_count): if attempt_count >= 5: return {'should_retry': False} # Exponential backoff: 2s, 4s, 8s, 16s, 32s (capped at 300s) delay = min(2 * (2 ** (attempt_count - 1)), 300) return {'should_retry': True, 'delay': delay} result = context.step( lambda _: call_external_api(), name='call-api', config=StepConfig(retry_strategy=retry_strategy) )

Annulation à intervalle fixe :

TypeScript
const orders = await context.step('query-orders', async () => { return await queryDatabase(event.userId); }, { retryStrategy: (error, attemptCount) => { if (attemptCount >= 3) { return { shouldRetry: false }; } return { shouldRetry: true, delay: { seconds: 5 } }; } });
Python
def retry_strategy(error, attempt_count): if attempt_count >= 3: return {'should_retry': False} return {'should_retry': True, 'delay': 5} orders = context.step( lambda _: query_database(event['userId']), name='query-orders', config=StepConfig(retry_strategy=retry_strategy) )

Nouvelle tentative conditionnelle (réessayez uniquement en cas d'erreurs spécifiques) :

TypeScript
const result = await context.step('call-rate-limited-api', async () => { const response = await fetch('https://api.example.com/data'); if (response.status === 429) throw new Error('RATE_LIMIT'); if (response.status === 504) throw new Error('TIMEOUT'); if (!response.ok) throw new Error(`API_ERROR_${response.status}`); return await response.json(); }, { retryStrategy: (error, attemptCount) => { // Only retry rate limits and timeouts const isRetryable = error.message === 'RATE_LIMIT' || error.message === 'TIMEOUT'; if (!isRetryable || attemptCount >= 3) { return { shouldRetry: false }; } // Exponential backoff: 1s, 2s, 4s (capped at 30s) const delay = Math.min(Math.pow(2, attemptCount - 1), 30); return { shouldRetry: true, delay: { seconds: delay } }; } });
Python
def retry_strategy(error, attempt_count): # Only retry rate limits and timeouts is_retryable = str(error) in ['RATE_LIMIT', 'TIMEOUT'] if not is_retryable or attempt_count >= 3: return {'should_retry': False} # Exponential backoff: 1s, 2s, 4s (capped at 30s) delay = min(2 ** (attempt_count - 1), 30) return {'should_retry': True, 'delay': delay} result = context.step( lambda _: call_rate_limited_api(), name='call-rate-limited-api', config=StepConfig(retry_strategy=retry_strategy) )

Désactiver les nouvelles tentatives :

TypeScript
const isDuplicate = await context.step('check-duplicate', async () => { return await checkIfOrderExists(event.orderId); }, { retryStrategy: () => ({ shouldRetry: false }) });
Python
is_duplicate = context.step( lambda _: check_if_order_exists(event['orderId']), name='check-duplicate', config=StepConfig( retry_strategy=lambda error, attempt: {'should_retry': False} ) )

Lorsque la stratégie de nouvelle tentative revientshouldRetry: false, l'étape échoue immédiatement sans nouvelle tentative. Utilisez-le pour les opérations qui ne doivent pas être renouvelées, telles que les contrôles d'idempuissance ou les opérations présentant des effets secondaires qui ne peuvent pas être répétés en toute sécurité.

Exceptions en dehors des étapes

Lorsqu'une exception non détectée se produit dans le code de votre gestionnaire mais en dehors de toute étape, le SDK marque l'exécution comme ayant échoué. Cela garantit que les erreurs dans la logique de votre application sont correctement capturées et signalées.

Scénario Que se passe-t-il Impact du mesurage
Exception dans le code du gestionnaire en dehors de toute étape Le SDK marque l'exécution comme ayant échoué et renvoie l'erreur. L'exception n'est pas automatiquement réessayée. Erreur concernant la taille de la charge utile

Pour activer la nouvelle tentative automatique pour le code sujet aux erreurs, associez-le à une étape avec une stratégie de nouvelle tentative. Les étapes fournissent une nouvelle tentative automatique avec une interruption configurable, tandis que le code en dehors des étapes échoue immédiatement.

Rétentatives du backend

Les nouvelles tentatives du backend ont lieu lorsque Lambda rencontre des défaillances d'infrastructure, des erreurs d'exécution ou lorsque le SDK ne peut pas communiquer avec le service d'exécution durable. Lambda réessaie automatiquement ces défaillances pour garantir que vos fonctions durables puissent se rétablir après des problèmes d'infrastructure transitoires.

Scénarios de nouvelle tentative du backend

Lambda réessaie automatiquement votre fonction lorsqu'elle rencontre les scénarios suivants :

  • Erreurs de service internes : lorsque Lambda ou le service d'exécution durable renvoie une erreur 5xx, indiquant un problème de service temporaire.

  • Limitation : lorsque votre fonction est limitée en raison de limites de simultanéité ou de quotas de service.

  • Délais d'expiration : lorsque le SDK ne parvient pas à atteindre le service d'exécution durable dans le délai imparti.

  • Échec de l'initialisation du sandbox : lorsque Lambda ne parvient pas à initialiser l'environnement d'exécution.

  • Erreurs d'exécution : lorsque le moteur d'exécution Lambda rencontre des erreurs extérieures au code de votre fonction, telles que out-of-memory des erreurs ou des pannes de processus.

  • Erreurs de jeton de point de contrôle non valides : lorsque le jeton de point de contrôle n'est plus valide, généralement en raison de changements d'état côté service.

Le tableau suivant décrit comment le SDK gère ces scénarios :

Scénario Que se passe-t-il Impact du mesurage
Erreur d'exécution en dehors du gestionnaire durable (OOM, délai d'attente, crash) Lambda réessaie automatiquement l'invocation. Le SDK se rejoue depuis le dernier point de contrôle, en sautant les étapes terminées. Taille de la charge utile d'erreur + 1 opération par nouvelle tentative
Erreur de service (5xx) ou délai d'expiration lors de l'appel/CheckpointDurableExecutionGetDurableExecutionState APIs Lambda réessaie automatiquement l'invocation. Le SDK se rejoue depuis le dernier point de contrôle. Taille de la charge utile d'erreur + 1 opération par nouvelle tentative
Throttling (429) ou jeton de point de contrôle non valide lors de l'appel/CheckpointDurableExecutionGetDurableExecutionState APIs Lambda réessaie automatiquement l'invocation avec un retard exponentiel. Le SDK se rejoue depuis le dernier point de contrôle. Taille de la charge utile d'erreur + 1 opération par nouvelle tentative
Erreur client (4xx, sauf 429 et jeton non valide) lorsque/CheckpointDurableExecutionGetDurableExecutionState APIs Le SDK marque l'exécution comme ayant échoué. Aucune nouvelle tentative automatique ne se produit car l'erreur indique un problème permanent. Erreur concernant la taille de la charge utile

Les nouvelles tentatives du backend utilisent un retard exponentiel et se poursuivent jusqu'à ce que la fonction réussisse ou que le délai d'exécution soit atteint. Pendant la rediffusion, le SDK ignore les points de contrôle terminés et poursuit l'exécution depuis la dernière opération réussie, garantissant ainsi que votre fonction ne réexécute pas le travail terminé.

Réessayez les meilleures pratiques

Suivez les meilleures pratiques suivantes lors de la configuration des stratégies de nouvelle tentative :

  • Configurez des stratégies de relance explicites : ne vous fiez pas au comportement de nouvelle tentative par défaut en production. Configurez des stratégies de nouvelles tentatives explicites avec un nombre maximum de tentatives et des intervalles d'attente adaptés à votre cas d'utilisation.

  • Utiliser des tentatives conditionnelles : implémentez une shouldRetry logique permettant de réessayer uniquement les erreurs transitoires (limites de débit, délais d'attente) et d'échouer rapidement en cas d'erreur permanente (échec de validation, introuvable).

  • Définissez le nombre maximum de tentatives approprié : équilibre entre résilience et temps d'exécution. Un trop grand nombre de tentatives peut retarder la détection des échecs, tandis qu'un nombre insuffisant peut entraîner des échecs inutiles.

  • Utilisez le ralentissement exponentiel : le ralentissement exponentiel réduit la charge sur les services en aval et augmente les chances de reprise après des défaillances transitoires.

  • Enveloppez le code sujet aux erreurs par étapes : le code en dehors des étapes ne peut pas être réessayé automatiquement. Intégrez les appels d'API externes, les requêtes de base de données et les autres opérations susceptibles d'entraîner des erreurs par étapes grâce à des stratégies de nouvelle tentative.

  • Surveillez les statistiques relatives aux nouvelles tentatives : suivez les opérations de nouvelle tentative par étapes et les échecs d'exécution sur Amazon CloudWatch afin d'identifier les modèles et d'optimiser les stratégies de nouvelles tentatives.