Go语言 从lambda事件或上下文动态检索SQS队列URL

czq61nw1  于 2022-12-16  发布在  Go
关注(0)|答案(2)|浏览(152)

我有一个lambda函数,它响应两个不同的SQS队列调用它(第二个队列是回退队列),因此我想动态地确定消息来自哪个队列,以便在处理完消息后删除它。
我可以创建EventSourceMapping来从两个队列中触发lambda,但我无法清楚地获取执行DeleteMessage调用所需的QueueURL。
EventSourceArn in the body of the event messages,我似乎可以使用GetQueueURL,但这将是一个额外的API调用。
避免这种情况的唯一方法(我能想到的)是将两个队列URL作为环境变量传入,并使用EventSourceArn中的队列名称来查找它。
有没有更好的方法?context中是否隐藏了一些没有记录的东西?

mefy6pfw

mefy6pfw1#

如果你使用lambda,SQS和一个事件源Map,那么你不需要手动从sqs中删除对象:When your function successfully processes a batch, Lambda deletes its messages from the queue
只需返回一个成功代码,消息就会自动从相关SQS队列中删除

mum43rcc

mum43rcc2#

您可以从其ARN(在事件中为EventSourceARN)重新构建队列URL。

package main

import (
    "context"
    "fmt"

    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    "github.com/aws/aws-sdk-go/aws/arn"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/sqs"
)

var client *sqs.SQS

func main() {
  client = sqs.New(session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    })))
    lambda.Start(Handle)
}

func Handle(ctx context.Context, event events.SQSEvent) {  
    for _, record := range event.Records {
        // Process message
        fmt.Printf(record.Body)

        // Rebuild Queue URL from ARN 
        queueArn, _ := arn.Parse(record.EventSourceARN)
        queueUrl := fmt.Sprintf("https://sqs.%v.amazonaws.com/%v/%v", queueArn.Region, queueArn.AccountID, queueArn.Resource)

        // Delete message from queue
        client.DeleteMessage(&sqs.DeleteMessageInput{
            QueueUrl:      &queueUrl,
            ReceiptHandle: &record.ReceiptHandle,
        })
    }
}

如果您使用的是非标准AWS分区(例如中国),您还需要更改URL的根域以匹配。

相关问题