使用AWS CDK(TypeScript)实现Lambda调用失败时事件转存DLQ
问题原因分析
你当前的配置无效,核心原因是:Lambda自身的DLQ(包括deadLetterQueue和onFailure: new SqsDlq()配置)仅对Lambda的异步调用生效,而Step Functions的LambdaInvoke组件默认使用同步调用(RequestResponse模式)**。这种模式下,Lambda执行失败会直接返回错误给Step Functions,不会触发Lambda的DLQ机制。
解决方案:在Step Functions层面处理失败并发送到DLQ
需要在Step Functions的流程中添加错误捕获逻辑,当LambdaInvoke步骤失败时,将原始输入事件发送到SQS DLQ。以下是修正后的代码实现:
import { Construct } from 'constructs'; import { Queue } from 'aws-cdk-lib/aws-sqs'; import { LambdaInvoke, SqsSendMessage } from 'aws-cdk-lib/aws-stepfunctions-tasks'; import { StateMachine, Fail, Catch, Error } from 'aws-cdk-lib/aws-stepfunctions'; import { MyLambda } from './path-to-your-my-lambda'; // 替换为你的MyLambda路径 class LambdaInvokeWithLambdaAndDlq extends Construct { dlq: Queue; lambda: MyLambda; lambdaInvoke: LambdaInvoke; constructor(scope: Construct, id: string) { super(scope, id); // 1. 创建DLQ队列 this.dlq = new Queue(this, 'dlq'); // 2. 创建Lambda函数,移除自身的DLQ配置 this.lambda = new MyLambda(this, 'my-lambda'); // 3. 定义发送失败输入到DLQ的Step Functions任务 const sendToDlq = new SqsSendMessage(this, 'SendToDLQ', { queue: this.dlq, messageBody: sfn.TaskInput.fromJsonPathAt('$'), // 将Step Functions当前上下文(即Lambda的原始输入)作为消息体 }); // 4. 定义LambdaInvoke步骤 this.lambdaInvoke = new LambdaInvoke(this, `lambda-invoke`, { lambdaFunction: this.lambda, resultSelector: { 'data.$': '$.Payload' }, resultPath: '$', }); // 5. 为LambdaInvoke添加错误捕获规则 this.lambdaInvoke.addCatch(sendToDlq, { errors: [Error.LAMBDA_SERVICE_EXCEPTION, Error.LAMBDA_FUNCTION_ERROR], // 捕获Lambda相关的两类错误 resultPath: '$', // 保留错误信息(可选) }); // 6. 发送到DLQ后终止流程(可选,根据业务需求调整) sendToDlq.next(new Fail(this, 'LambdaInvokeFailed', { cause: 'Lambda调用失败,输入已发送至DLQ', error: 'LambdaInvokeError', })); // 若需要创建完整的状态机,可添加以下代码 // new StateMachine(this, 'StateMachine', { // definition: this.lambdaInvoke, // }); } }
关键说明
- 权限自动处理:CDK会自动为Step Functions的执行角色添加发送消息到SQS DLQ的权限,无需手动配置IAM策略。
- 错误类型选择:
Error.LAMBDA_SERVICE_EXCEPTION:捕获Lambda服务端的错误(如资源不足、超时)Error.LAMBDA_FUNCTION_ERROR:捕获Lambda函数代码抛出的错误- 若要捕获所有错误,可将
errors设为['States.ALL']
- 异步调用场景(可选):如果业务允许Step Functions不等待Lambda执行完成,可将
LambdaInvoke的invocationType设为InvocationType.EVENT(异步模式),此时Lambda自身的DLQ配置会生效,但Step Functions无法获取Lambda的执行结果。
内容的提问来源于stack exchange,提问作者Estevam Furtado
相关产品推荐
相关产品推荐

