Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 如何使来自Lambda的批处理中的特定SQS消息失败?_Node.js_Amazon Web Services_Aws Lambda_Amazon Sqs - Fatal编程技术网

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

Node.js 如何使来自Lambda的批处理中的特定SQS消息失败?,node.js,amazon-web-services,aws-lambda,amazon-sqs,Node.js,Amazon Web Services,Aws Lambda,Amazon Sqs,我有一个带有SQS触发器的Lambda。当它被点击时,来自SQS的一批记录进入(我认为通常一次大约10条)。如果我从处理程序返回失败的状态代码,则将重试所有10条消息。如果我返回一个成功代码,它们将全部从队列中删除。如果10条消息中有1条失败,而我只想重试那一条呢 exports.handler = async (event) => { for(const e of event.Records){ try { let body = JSON

我有一个带有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.'
    };
};

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

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


我建议您设置一个失败计数,这样,如果所有消息都失败了,您只需返回所有消息的失败状态,否则,如果失败计数小于10,则您可以单独将失败消息发送回队列。

您需要以不同的方式设计应用程序。这里有一些想法不是最好的,但可以解决您的问题

解决方案1:

  • 创建sqs交付队列-sq1
  • 根据延迟要求sq2创建延迟队列
  • 创建死信队列sdl
  • 现在,在lambda函数内部,如果消息在sq1中失败,则在sq1上删除它,并将其放到sq2上重试。异步调用的任何lambda函数都会在事件被丢弃之前重试两次。如果重试失败

  • 如果重试后再次失败,请移动到死信队列sdl

注意:当最初创建并启用SQS事件源映射时,或在没有流量的时段后首次出现时,Lambda服务将开始使用五个并行长轮询连接轮询SQS队列,根据AWS文档,从AWS Lambda到SQS的长轮询的默认持续时间为20秒

解决方案2:

使用AWS STEP函数

StepFunction将调用lambda,并在需要时使用可配置的指数后退处理失败时的重试逻辑

**解决方案3:**

CloudWatch计划事件以触发轮询失败的Lambda函数

给定事件源的错误处理取决于Lambda的调用方式。Amazon CloudWatch事件异步调用Lambda函数

您必须在成功处理消息后以编程方式从中删除每个消息


因此,如果任何消息失败,您可以将标志设置为true,并且根据此标志,您可以在处理批处理中的所有消息后引发错误,这样成功的消息将被删除,其他消息将根据重试策略重新处理。

谢谢。我找到了一篇适合我的用例的文章。如果我们换一种方式:从队列中删除所有成功和失败的项目(这将使批处理中的项目,但未从队列中删除的项目重新运行)。这行得通吗?是的,你也可以用这种方法,使用。但是,最好采用另一种方式,因为在大多数情况下,您不会出现任何故障,因此,最好仅手动发回故障的故障,否则您总是为成功的故障向deleteMessage发出I/O调用,这将造成成本高昂且效率低下的情况,可能会延迟一段时间,但您只能在失败计数不等于消息计数且大于0的情况下执行单个删除。这样,当一切正常时,就可以避免额外的I/O。