如何使来自 Lambda 的批处理中的特定 SQS 消息失败?

use*_*094 20 amazon-sqs amazon-web-services node.js aws-lambda

我有一个带有 SQS 触发器的 Lambda。当它被击中时,来自 SQS 的一批记录进来(我认为通常一次大约 10 个)。如果我从处理程序返回失败的状态代码,将重试所有 10 条消息。如果我返回成功代码,它们都会从队列中删除。如果这 10 条消息中有 1 条失败,而我只想重试那一条怎么办?

exports.handler = async (event) => {

    for(const e of event.Records){
        try {
            let body = JSON.parse(e.body);
            // do things
        }
        catch(e){
            // one message failed, i want it to be retried
        }        
    }

    // returning this causes ALL messages in 
    // this batch to be removed from the queue
    return {
        statusCode: 200,
        body: 'Finished.'
    };
};
Run Code Online (Sandbox Code Playgroud)

我是否必须手动将该消息重新添加回队列?或者我可以从我的处理程序返回一个状态,指示一条消息失败并应该重试?

use*_*461 16

根据 AWS文档,SQS 事件源映射现在支持开箱即用地处理部分故障。链接文章的要点如下:

  1. 包含ReportBatchItemFailures在您的EventSourceMapping配置中
  2. 失败时的响应语法必须修改为:
{
  "batchItemFailures": [
    { "itemIdentifier": "id2" },
    { "itemIdentifier": "id4" }
  ]
}
Run Code Online (Sandbox Code Playgroud)

其中id2和id4是批量失败的messageId。

  1. 按原样引用文档:

如果您的函数返回以下任意内容,则 Lambda 会将批次视为完全成功

  • batchItemFailure列表
  • batchItemFailure列表
  • 一个空的EventResponse
  • 空值EventResponse

如果您的函数返回以下任一内容,则 Lambda 会将批次视为完全失败:

  • 无效的 JSON 响应
  • 空字符串itemIdentifier
  • 空值itemIdentifier
  • itemIdentifier键名称错误的AN
  • itemIdentifier消息 ID 不存在的值

  • 第 1 步很重要。请务必将 `"FunctionResponseTypes": ["ReportBatchItemFailures"]` 添加到云形成模板中的 Lambda 的 EventSourceMapping 资源。 (3认同)

Dei*_*eiv 7

是的,您必须手动将失败的消息重新添加回队列。

我建议做的是设置失败计数,这样如果所有消息都失败了,您可以简单地返回所有消息的失败状态,否则如果失败计数 < 10,那么您可以单独将失败的消息发送回队列。

  • 如果我们反其道而行之:从队列中删除那些成功的项目并让所有失败的项目(这旨在使那些在批次中但未从队列中删除的项目重新运行)。那行得通吗? (2认同)
  • 是的,您也可以使用[删除消息调用](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessage.html)这样做。但是,最好以其他方式执行此操作,因为在大多数情况下您不会遇到任何失败,因此最好仅手动发回失败的消息,否则您总是对 deleteMessage 进行 I/O 调用以获得成功,这将是昂贵且低效的 (2认同)