我在想什么,我真的找不到关于它的信息。也许不是要走的路,但是,我只想知道。
这是关于Lambda分批工作的。我知道我可以设置Lambda来使用批处理消息。在我的Lambda函数中,我迭代每条消息,如果一条消息失败,则Lambda存在。然后循环再次开始。
我想知道稍微不同的方法 假设我有3条消息: A , B 和 C 。我也分批服用。现在,如果消息B失败(例如API调用失败),我将消息B返回给SQS,并继续处理消息C。
有可能吗?如果是,这是一个好方法吗?因为我看到我需要在Lambda中实现一些额外的复杂性,所以不需要。
谢谢
答案 0 :(得分:3)
有一篇很棒的文章here。与您相关的部分是...
最后一个要点是我如何处理相同的问题。与其立即返回错误,不如存储它们或注意已发生错误,而是继续处理批处理中的其余消息,而不是立即返回错误。在处理结束时,返回或引发错误,以使SQS-> lambda触发器知道不删除失败的消息。您的lambda处理程序将删除所有成功的消息。
sqs = boto3.client('sqs')
def handler(event, context):
failed = False
for msg in event['Records']:
try:
# Do something with the message.
handle_message(msg)
except Exception:
# Ok it failed, but allow the loop to finish.
logger.exception('Failed to handle message')
failed = True
else:
# The message was handled successfully. We can delete it now.
sqs.delete_message(
QueueUrl=<queue_url>,
ReceiptHandle=msg['receiptHandle'],
)
# It doesn't matter what the error is. You just want to raise here
# to ensure the trigger doesn't delete any of the failed messages.
if failed:
raise RuntimeError('Failed to process one or more messages')
def handle_msg(msg):
...
答案 1 :(得分:2)
截至2019年11月,AWS has introduced的概念是函数错误Bisect,以及最大重试次数。如果您的函数是幂等的,则可以使用它。
在这种方法中,即使批处理中的一项失败,也应该从函数中引发错误。 AWS将批次分为两部分,然后重试。现在,该批次的一半应该成功通过。对于另一半,此过程将继续进行,直到隔离不良记录为止。
答案 2 :(得分:1)
就像所有架构决策一样,这取决于您的目标以及您为更复杂而愿意进行的交易。使用SQS将使您能够按顺序处理消息,以便重试不会阻止其他消息。复杂性是否值得,取决于您担心邮件被阻止的原因。
我建议阅读有关Lambda retry behavior和死信队列的信息。
答案 3 :(得分:1)
如果您只想重试一批邮件中失败的邮件,则完全可以,但是会增加一些复杂性。
实现此目的的一种可能方法是遍历事件列表(例如[eventA,eventB,eventC]),对于每次执行,如果事件失败,则追加到失败事件列表中。然后,使用一个最终案例检查失败事件列表中是否包含任何内容,如果有,则手动将消息发送回SQS(使用SQS sendMessageBatch)。 / p>
但是,您应该注意,由于您是手动将事件插入回去,因此这会将事件置于队列的末尾。
如果任何事情都可以解决您遇到的问题而没有太多复杂性,那么任何事情都可以成为“好方法”,在这种情况下,必须重新执行成功的事件绝对是您可以通过这种方式解决的问题。
答案 4 :(得分:1)
对于Node.js,请检出https://www.npmjs.com/package/@middy/sqs-partial-batch-failure。
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())
查看https://medium.com/@brettandrews/handling-sqs-partial-batch-failures-in-aws-lambda-d9d6940a17aa了解更多详细信息。