Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/13.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
Amazon web services 批量处理AWS Lambda消息_Amazon Web Services_Aws Lambda_Amazon Sqs - Fatal编程技术网

Amazon web services 批量处理AWS Lambda消息

Amazon web services 批量处理AWS Lambda消息,amazon-web-services,aws-lambda,amazon-sqs,Amazon Web Services,Aws Lambda,Amazon Sqs,我想知道一些事情,但我真的找不到关于它的信息。也许这不是去的路,但是,我只是想知道 这是关于Lambda分批工作的。我知道我可以设置Lambda来使用批处理消息。在Lambda函数中,我迭代每条消息,如果其中一条失败,Lambda退出。循环又开始了 我想知道稍微不同的方法 让我们假设我有三条消息:A、B和C。我也分批服用。现在,如果消息B失败(例如API调用失败),我将消息B返回给SQS并继续处理消息C 可能吗?如果是,这是一个好方法吗?因为我看到我需要在Lambda中实现一些额外的复杂度 谢谢

我想知道一些事情,但我真的找不到关于它的信息。也许这不是去的路,但是,我只是想知道

这是关于Lambda分批工作的。我知道我可以设置Lambda来使用批处理消息。在Lambda函数中,我迭代每条消息,如果其中一条失败,Lambda退出。循环又开始了

我想知道稍微不同的方法 让我们假设我有三条消息:ABC。我也分批服用。现在,如果消息B失败(例如API调用失败),我将消息B返回给SQS并继续处理消息C

可能吗?如果是,这是一个好方法吗?因为我看到我需要在Lambda中实现一些额外的复杂度


谢谢

与所有架构决策一样,这取决于您的目标以及您愿意用什么来换取更高的复杂性。使用SQS将允许您无序处理消息,以便重试不会阻止其他消息。这是否值得这么复杂取决于您为什么担心邮件被阻止


我建议您阅读关于和死信队列的内容。

如果您只想重试一批消息中失败的消息,这是完全可行的,但会增加一些复杂性

实现这一点的一种可能方法是迭代事件列表(例如[eventA、eventB、eventC]),对于每次执行,如果事件失败,则附加到失败事件列表中。然后,创建一个结束案例,检查失败事件列表中是否有任何内容,如果有,则手动将消息发送回SQS(使用)

但是,您应该注意,这会将事件放在队列的末尾,因为您要手动将它们插回队列


任何事情都可以是一个“好方法”,如果它解决了您正在遇到的问题而没有太多复杂性,那么在这种情况下,必须重新执行成功事件的问题肯定是一个您可以通过这种方式解决的问题。

有一篇优秀的文章。你的相关部分是

  • 使用batchSize为1,以便消息自行成功或失败
  • 确保您的处理是幂等的,这样在额外的处理成本之外,重新处理消息不会有害
  • 处理函数代码中的错误,方法可能是捕获错误并将消息发送到死信队列进行进一步处理
  • 成功处理消息后,在函数中手动调用DeleteMessage API。
最后一点是我如何处理同样的问题。不要立即返回错误,而是存储它们或注意发生了错误,然后继续处理批处理中的其余消息。在处理结束时,返回或引发错误,以便SQS->lambda触发器知道不删除失败的消息。lambda处理程序将已删除所有成功消息

sqs=boto3.client('sqs'))
def处理程序(事件、上下文):
失败=错误
对于事件['Records']中的消息:
尝试:
#对消息做点什么。
处理消息(msg)
除例外情况外:
#好的,它失败了,但允许循环完成。
logger.exception('处理消息失败')
失败=真
其他:
#消息已成功处理。我们现在可以删除它。
sqs.delete_消息(
QueueUrl=,
ReceiptHandle=msg['ReceiptHandle'],
)
#错误是什么并不重要。你只想在这里长大
#以确保触发器不会删除任何失败的消息。
如果失败:
raise RUNTIMERROR('处理一条或多条消息失败')
def handle_味精(味精):
...
对于Node.js,请签出

查看更多详细信息。

自2019年11月起,函数错误对分的概念以及最大重试次数。如果函数是幂等的,则可以使用此函数


在这种方法中,即使批处理中有一项失败,也应该从函数中抛出一个错误。AWS将批处理一分为二,然后重试。现在,批处理的一半应该成功通过。对于另一半,该过程将继续,直到不良记录被隔离。

感谢您的回复。你有没有一个实施的例子。我将有消息连接到数据库的肯定。任何例子都值得赞赏。@VedranMaricevic我根据要求添加了一个例子。太棒了。谢谢。在faiure的情况下,如果您继续向队列中添加消息,很可能会再次失败,最好的方法是在出现任何失败时删除成功消息并引发异常,然后让DLQ完成任务。根据文档,这仅适用于Kinesis和Dynamo streams。不幸的是,我没有看到SQS触发器具有相同的功能。
const middy = require('@middy/core')
const sqsBatch = require('@middy/sqs-partial-batch-failure')

const originalHandler = (event, context, cb) => {
  const recordPromises = event.Records.map(async (record, index) => { /* Custom message processing logic */ })
  return Promise.allSettled(recordPromises)
}

const handler = middy(originalHandler)
  .use(sqsBatch())