如何从Lambda触发器将消息返回给SQS [英] How do I return a message back to SQS from lambda trigger

查看:161
本文介绍了如何从Lambda触发器将消息返回给SQS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have lambda trigger that reads messages from SQS queue. In some conditions, the message may not be ready for processing so I'd like to put the message back in queue for 1min and try again. Currently, I am create another copy of this customer record and posting this new copy in the queue. Is there a reason/way for me to keep the original record in queue as opposed to creating a new one

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函数的理想设置.

This is not an ideal setup for SQS triggering Lambda functions.

我的测试表明,即使提供了延迟"设置,发送到SQS的邮件也会立即触发Lambda函数.因此,将消息放回SQS队列将导致Lambda立即再次触发.

My testing shows that messages sent to SQS will immediately trigger the Lambda function, even if a Delay setting is provided. Therefore, putting a message back onto the SQS queue will cause Lambda to fire again straight after.

为避免Lambda不断检查邮件是否已准备好处理的情况,我建议:

To avoid a situation where Lambda is continually checking whether a message is ready for processing, I would recommend:

  • 使用Amazon CloudWatch Events按计划(例如,每2分钟)触发Lambda函数
  • Lambda函数应从队列中提取消息,并检查它们是否准备好进行处理.
    • 如果它们准备就绪,请对其进行处理并将其删除
    • 如果尚未准备好 ,则使用 Delay 设置将其推回队列,并删除原始消息
    • Use Amazon CloudWatch Events to trigger a Lambda function on a schedule (eg every 2 minutes)
    • The Lambda function should pull messages from the queue and check if they are ready to process.
      • If they are ready, then process them and delete them
      • If they are not ready, then push them back onto the queue with a Delay setting and delete the original message

      请注意,这与让SQS直接触发Lambda不同.相反,Lambda函数应该调用ReceiveMessages()来获取消息本身,这允许Delay函数在两次检查之间增加一些时间.

      Note that this is different to having SQS directly trigger Lambda. Instead, the Lambda function should call ReceiveMessages() to obtain the message(s) itself, which allows the Delay function to add some time between checks.

      另一个选项:您可以通过删除消息来简单地利用默认可见性超时设置,而不是将消息重新插入队列中.从队列中读取但未被删除的消息将自动重新出现"在队列中.您可以将其用作重试"时间段.但是,这意味着您将需要自己处理死信"处理(例如,如果在 n 尝试后无法处理消息).

      Another option: Instead of re-inserting a message into the queue, you could simply take advantage of the Default Visibility Timeout setting by not deleting the message. A message that is read from the queue, but not deleted, will automatically "reappear" on the queue. You could use this as the "retry" time period. However, this means you will need to handle Dead Letter processing yourself (eg if a message fails to be processed after n tries).

      这篇关于如何从Lambda触发器将消息返回给SQS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆