从Lambda事件或上下文动态检索SQS队列URL

huangapple go评论79阅读模式
英文:

Retrieve the SQS Queue URL dynamically from the lambda event or context

问题

我有一个单一的 Lambda 函数,可以响应两个不同的 SQS 队列的调用(第二个队列是备用队列),因此我想动态确定消息来自哪个队列,以便在处理完后将其删除。

我可以创建 EventSourceMapping 来触发 Lambda 函数从两个队列接收消息,但我无法清晰地获取我需要的 QueueURL,以便执行 DeleteMessage 调用。我正在使用 AWS 的 Golang SDK。

在事件消息的正文中有 EventSourceArn,似乎我可以使用 GetQueueURL,但那将是一个额外的 API 调用。

我所能想到的唯一避免这种情况的方法是将两个队列的 URL 作为环境变量传递,并使用 EventSourceArn 中的队列名称来查找它。

是否有更好的方法?是否有在上下文中隐藏的未记录的内容?

英文:

I have a single lambda function which responds to two different SQS queues invoking it (the second one is a back-off queue) and so I want to dynamically determine which queue the message came from, so that I can remove it once it has been processed.

I am able to create the EventSourceMapping to trigger the lambda from both queues, but I cannot see how I cleanly retrieve the QueueURL I need in order to perform a DeleteMessage call. I am using the AWS Golang SDK.

There is the EventSourceArn in the body of the event messages and it seems I could use GetQueueURL but that would be an additional API call.

The only way to avoid that (I can think of) is to pass both queue URLs in as environment variables and use the queue name from EventSourceArn to find it.

Is there a better way that this? Is there something hiding in the context that isn't documented?

答案1

得分: 2

你可以根据事件中的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 {
		// 处理消息
		fmt.Printf(record.Body)

		// 从ARN重建队列URL
		queueArn, _ := arn.Parse(record.EventSourceARN)
		queueUrl := fmt.Sprintf("https://sqs.%v.amazonaws.com/%v/%v", queueArn.Region, queueArn.AccountID, queueArn.Resource)

		// 从队列中删除消息
		client.DeleteMessage(&sqs.DeleteMessageInput{
			QueueUrl:      &queueUrl,
			ReceiptHandle: &record.ReceiptHandle,
		})
	}
}

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

英文:

You can rebuild the queue URL from its ARN which you have in the event as EventSourceARN.

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,
		})
	}
}

If you are using a non-standard AWS partition (e.g. China) you will also need to change the root domain of the URL to match.

答案2

得分: 1

如果您正在使用Lambda、SQS和事件源映射,那么您不需要手动从SQS中删除对象:当函数成功处理一个批次时,Lambda会从队列中删除其消息

只需返回一个成功代码,消息将自动从相关的SQS队列中删除。

英文:

If you are using lambda, SQS and an event-source-mapping, then you don't have to manually delete objects from sqs: When your function successfully processes a batch, Lambda deletes its messages from the queue

Just return a success code, and the message will automatically be deleted from the relevant SQS queue

huangapple
  • 本文由 发表于 2021年8月13日 00:13:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/68760921.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定