Aws lambda 如何从lambda触发器向SQS返回消息

Aws lambda 如何从lambda触发器向SQS返回消息,aws-lambda,amazon-sqs,Aws Lambda,Amazon Sqs,我有从SQS队列读取消息的lambda触发器。在某些情况下,消息可能未准备好处理,因此我希望将消息放回队列中1分钟,然后重试。目前,我正在创建此客户记录的另一份副本,并将此新副本发布到队列中。我是否有理由/方法将原始记录保留在队列中而不是创建新记录 def postToQueue(customer): if 'attemptCount' in customer.keys(): attemptCount = int(customer["attemptCount"]) +

我有从SQS队列读取消息的lambda触发器。在某些情况下,消息可能未准备好处理,因此我希望将消息放回队列中1分钟,然后重试。目前,我正在创建此客户记录的另一份副本,并将此新副本发布到队列中。我是否有理由/方法将原始记录保留在队列中而不是创建新记录

def postToQueue(customer):

    if 'attemptCount' in customer.keys():
        attemptCount = int(customer["attemptCount"]) + 1
    else:
        attemptCount = 2
    customer["attemptCount"] = attemptCount

    # Get the service resource
    sqs = boto3.resource('sqs')

    # Get the queue
    queue = sqs.get_queue_by_name(QueueName='testCustomerQueue')
response = queue.send_message(MessageBody=json.dumps(customer), DelaySeconds=60)

    print('customer postback: ', customer)
    print ('response from writing ot the queue is: ', response)

#main function
for record in event['Records']:
    if 'body' in record.keys():
        customer = json.loads(record['body'])
        print("attempting to process customer", customer, " at: ", datetime.datetime.now())
        if (not ifReadyToProcess(customer)):
            postToQueue(customer)
        else:
            processCustomer(customer)

这不是SQS触发Lambda函数的理想设置

我的测试表明,发送到SQS的消息将立即触发Lambda函数,即使提供了延迟设置。因此,将消息放回SQS队列将导致Lambda在之后立即再次触发

为避免Lambda不断检查消息是否已准备好进行处理,我建议:

  • 使用Amazon CloudWatch事件按计划触发Lambda函数(如每2分钟一次)
  • Lambda函数应该从队列中提取消息,并检查它们是否准备好进行处理。
    • 如果已准备好,则处理并删除它们
    • 如果它们没有准备好,则使用延迟设置将它们推回到队列中,并删除原始消息
注意,这不同于让SQS直接触发Lambda。相反,Lambda函数应该调用
ReceiveMessages()
来获取消息本身,这允许Delay函数在检查之间增加一些时间


另一个选项:不需要将消息重新插入队列,只需利用默认可见性超时设置,不删除消息即可。从队列读取但未删除的消息将自动“重新出现”在队列上。您可以将其用作“重试”时间段。但是,这意味着您将需要自己处理死信处理(例如,如果在n次尝试后无法处理消息)。

这不是SQS触发Lambda函数的理想设置

我的测试表明,发送到SQS的消息将立即触发Lambda函数,即使提供了延迟设置。因此,将消息放回SQS队列将导致Lambda在之后立即再次触发

为避免Lambda不断检查消息是否已准备好进行处理,我建议:

  • 使用Amazon CloudWatch事件按计划触发Lambda函数(如每2分钟一次)
  • Lambda函数应该从队列中提取消息,并检查它们是否准备好进行处理。
    • 如果已准备好,则处理并删除它们
    • 如果它们没有准备好,则使用延迟设置将它们推回到队列中,并删除原始消息
注意,这不同于让SQS直接触发Lambda。相反,Lambda函数应该调用
ReceiveMessages()
来获取消息本身,这允许Delay函数在检查之间增加一些时间


另一个选项:不需要将消息重新插入队列,只需利用默认可见性超时设置,不删除消息即可。从队列读取但未删除的消息将自动“重新出现”在队列上。您可以将其用作“重试”时间段。但是,这意味着您需要自己处理死信处理(例如,如果在n次尝试后邮件无法处理)。

谢谢。你能澄清一下我是如何阅读和将消息推回到队列中的吗。这正是我要找的。Lambda函数应该从队列中提取消息,并检查它们是否准备好处理。如果它们准备好了,则处理它们,如果它们没有准备好,则删除它们,然后使用延迟设置将它们推回到队列中,并删除原始消息“您并不是真的“将它们推回去”。而是将新消息推送到队列中。Delay参数将在所需的时间段内隐藏它,以便当Lambda代码从队列中提取消息时,它们不会出现。请注意,这不同于让SQS直接触发Lambda。您的Lambda函数可以使用和。谢谢。你能澄清一下我是如何阅读和将消息推回到队列中的吗。这正是我要找的。Lambda函数应该从队列中提取消息,并检查它们是否准备好处理。如果它们准备好了,则处理它们,如果它们没有准备好,则删除它们,然后使用延迟设置将它们推回到队列中,并删除原始消息“您并不是真的“将它们推回去”。而是将新消息推送到队列中。Delay参数将在所需的时间段内隐藏它,以便当Lambda代码从队列中提取消息时,它们不会出现。请注意,这不同于让SQS直接触发Lambda。您的Lambda函数可以使用和。