Quand une invocation Lambda asynchrone échoue tous ses réessais, l’événement est supprimé. Pas journalisé quelque part de commode, pas stationné — disparu. Une file d’échec (DLQ) ou une destination on-failure est la seule chose entre un mauvais déploiement et quelques heures de notifications S3, d’événements EventBridge ou de messages SNS perdus en silence. Les destinations sont le mécanisme plus récent et plus riche, et le bon défaut; les DLQ restent correctes là où elles existent. Ce qui compte, c’est que chaque fonction asynchrone ait l’un des deux, et que quelque chose le surveille.
Ce qui se passe
Lambda a trois modèles d’invocation, et la gestion des échecs diffère nettement entre eux — la plupart de la confusion sur les DLQ est en réalité une confusion sur le modèle en jeu.
Les invocations synchrones (API Gateway, ALB, appels directs) retournent les erreurs à l’appelant; Lambda ne réessaie rien et ni les DLQ ni les destinations ne s’appliquent. Les mappages de source d’événements — le modèle par sondage pour SQS, Kinesis et DynamoDB Streams — gèrent l’échec à la source : une file SQS utilise sa propre politique de redrive vers une DLQ au niveau de la file, et les mappages Kinesis/DynamoDB ont leurs propres réglages de réessai, de bissection et de destination on-failure. Une DLQ de fonction configurée sur une fonction pilotée par SQS ne fait rien; c’est la politique de redrive de la file qui attrape les messages empoisonnés.
Restent les invocations asynchrones — notifications S3, SNS, EventBridge, et tout ce qui est invoqué avec InvocationType=Event. Lambda les met en file à l’interne, tente la livraison, et sur erreur de fonction réessaie jusqu’à deux fois de plus (configurable 0-2 via MaximumRetryAttempts) avec recul, en écartant les événements plus vieux que MaximumEventAgeInSeconds (jusqu’à 6 heures). Après le dernier échec, l’événement va à la DLQ ou à la destination on-failure si configurée, et s’évapore autrement.
Les deux mécanismes de capture diffèrent par la charge utile et la portée. Une DLQ est une file SQS ou un sujet SNS qui reçoit l’événement original seulement — pas de message d’erreur, pas de contexte. Les destinations (OnFailure et aussi OnSuccess) peuvent cibler SQS, SNS, une autre fonction Lambda ou EventBridge, et livrent une enveloppe contenant l’événement original plus le type d’erreur, le message, un résumé de la trace et le contexte de la requête. Pour déboguer à 3 h du matin, cette enveloppe fait la différence entre savoir pourquoi ça a échoué et le rejouer à l’aveugle pour le découvrir.
Quoi vérifier en premier
- Quel modèle d’invocation chaque fonction utilise réellement. Le type de déclencheur détermine si la capture d’échec au niveau de la fonction s’applique même.
- Si les fonctions asynchrones ont quoi que ce soit de configuré. La plupart des comptes que nous auditons ont plusieurs fonctions asynchrones sans DLQ, sans destination, et sans la moindre idée que des événements tombent.
- Si la DLQ existante a déjà été lue. Une DLQ avec 14 000 messages, sans consommateur ni alarme, c’est un dépotoir, pas un filet de sécurité.
- Les permissions IAM. Le rôle d’exécution de la fonction a besoin de
sqs:SendMessage,sns:Publish,lambda:InvokeFunctionouevents:PutEventssur la cible — sans quoi la capture d’échec échoue elle-même, en silence.
Comment vérifier
Inspectez la configuration asynchrone d’une fonction :
aws lambda get-function-event-invoke-config --function-name my-function
Un ResourceNotFoundException signifie que tout est aux défauts : deux réessais, âge maximal de six heures, pas de destination. Vérifiez la présence d’une DLQ ancienne mode :
aws lambda get-function-configuration --function-name my-function \
--query 'DeadLetterConfig'
Dans la console, les deux vivent sous Lambda > Functions > (fonction) > Configuration > Asynchronous invocation. Les métriques CloudWatch qui vous disent que des événements se perdent sont AsyncEventsDropped et DeadLetterErrors (les échecs d’écriture vers la DLQ elle-même) dans l’espace de noms AWS/Lambda. Les détails du modèle d’invocation sont documentés à https://docs.aws.amazon.com/lambda/.
La marche à suivre
- Inventoriez les fonctions asynchrones. Listez les fonctions et leurs déclencheurs; tout ce qui est nourri par S3, SNS ou EventBridge, ou invoqué en
Eventpar votre propre code, est dans la portée. - Créez une file d’échec par fonction (ou par service). Une file SQS avec une rétention de 14 jours vous donne la fenêtre maximale pour remarquer et rejouer. Les files par fonction rendent l’attribution triviale; une file partagée par service est acceptable si l’enveloppe identifie la source.
- Configurez une destination OnFailure qui pointe dessus.
aws lambda put-function-event-invoke-config \
--function-name my-function \
--maximum-retry-attempts 2 \
--maximum-event-age-in-seconds 21600 \
--destination-config '{"OnFailure":{"Destination":"arn:aws:sqs:ca-central-1:123456789012:my-function-failures"}}'
- Accordez au rôle d’exécution la permission de livrer. Ajoutez
sqs:SendMessagesur l’ARN de la file au rôle de la fonction. Testez en déployant une version qui échoue exprès en pré-production et en confirmant que l’événement enveloppé atterrit. - Alarmez sur la file, pas sur l’impression. Une alarme CloudWatch sur
ApproximateNumberOfMessagesVisible > 0pour la file d’échec transforme la perte de données silencieuse en alerte. Intégrez-la à la même base d’alarmes que tout le reste — voir la base d’alarmes CloudWatch. - Bâtissez le chemin de rejeu avant d’en avoir besoin. Un petit script qui lit l’enveloppe de destination, extrait l’événement original et ré-invoque la fonction transforme un mauvais déploiement en « redrainer la file » plutôt qu’en projet de reconstruction de données.
- Ajustez les réessais par charge de travail. Les webhooks de paiement peuvent justifier
MaximumRetryAttempts=0et une capture immédiate (les réessais dupliquent les effets de bord); les jobs d’enrichissement idempotentes peuvent garder les deux réessais et les six heures.
Quand ce n’est pas la bonne approche
Pour les fonctions pilotées par SQS, configurez plutôt la politique de redrive sur la file source — une DLQ de fonction y est de la configuration morte. Pour les flux Kinesis et DynamoDB, utilisez la destination on-failure et les réglages de bissection du mappage de source d’événements, qui comprennent les lots. Et si une charge de travail tolère réellement la perte — pings d’analytique échantillonnés, préchauffage de cache au mieux — une destination plus des alarmes plus de l’outillage de rejeu, c’est du processus pour le processus; prenez la décision de perte explicitement et écrivez-la.
Erreurs fréquentes
- Configurer une DLQ sur une fonction dont le déclencheur est un mappage de source d’événements SQS et croire que les messages empoisonnés sont gérés.
- Oublier la permission IAM pour la destination, si bien que la capture d’échec échoue — visible seulement dans la métrique
DeadLetterErrorsque personne ne trace. - Aucune alarme sur la file d’échec, et découvrir trois semaines d’événements perdus pendant une enquête sans rapport.
- Choisir des DLQ ordinaires pour les nouveaux montages et perdre le contexte d’erreur que les destinations auraient inclus gratuitement.
Prévention
- Faites de la destination OnFailure une partie du module de fonction dans votre IaC, pour que chaque nouvelle fonction asynchrone en reçoive une sans que personne s’en souvienne.
- Alarmez sur
AsyncEventsDroppedà l’échelle du compte — elle devrait toujours être à zéro. - Incluez le script de rejeu dans le cahier d’exploitation du service et testez-le chaque trimestre, comme une restauration de sauvegarde.
- Revoyez
MaximumEventAgeInSecondscontre la vraie tolérance en aval; six heures de réessais contre une dépendance brisée peuvent être pires qu’échouer vite.
Les événements en échec sont inévitables; les perdre est un choix que vous faites en laissant la configuration de destination vide. Si personne dans votre équipe ne possède vraiment l’environnement AWS de bout en bout, c’est la racine de la plupart de ces problèmes — Stack Harbor opère des comptes AWS au quotidien sous Opérations AWS, et vous pouvez réserver une revue AWS.