我试图限制并行运行的并发函数的数量。我的lambda的触发器是SQS队列中的一条消息,如您在我的serverless.yml中看到的:
receiver:
handler: src/receiver.handler
timeout: 30
events:
- sqs:
arn: ${queueArn}
batchSize: 1
reservedConcurrency: 1
我使用“ reservedConcurrency:1”将并发执行的次数限制为1。我在AWS UI中验证了功能“接收器”配置,并且“保留并发”也在那里设置为1。
不确定我丢失了什么,因为我仍然看到日志和AWS SQS UI都在运行数百个执行。
答案 0 :(得分:0)
SQS / Lambda集成不适用于低于5的保留并发。
如果您在函数上配置了保留并发,请设置最少5个并发执行,以减少Lambda调用函数时节流错误的机会。
运行中的消息不仅是Lambda函数当前正在处理的消息。它还包括由于Lambda函数上的可用并发不足而失败并返回到队列的消息-即使大多数尝试将失败,它们也将在尝试过程中处于运行状态。如果将保留的并发设置为0,则应该会发现所有处理都停止了,但是由于仍在尝试进行处理,因此仍有一些消息在运行中。
答案 1 :(得分:0)
Edouard 链接到一篇中等文章,该文章解释了此问题的更多解决方案 (https://medium.com/@zaccharles/lambda-concurrency-limits-and-sqs-triggers-dont-mix-well-sometimes-eb23d90122e0)。
但是,我没有发现它们中的任何一个对于限制 lambda 集成使用的 SQS 消息的不可配置的 5 个查询的用例特别有用。
我的解决方案:
processDatastoreHydrationMessages:
handler: src/hydrateDatastores/processMessagesHandler.handler
description: "Query SQS for a message and process it."
memorySize: 440
events:
- schedule: rate(2 minutes)
然后,在处理程序内部:
const sqsClient = new SQS({ region: getRegion() });
const documentClient = new DynamoDB.DocumentClient({ region: getRegion() });
console.log('Querying queue');
const response = await sqsClient
.receiveMessage({ QueueUrl: hydrationCommon.hydrationQueueUrl, MaxNumberOfMessages: 1, VisibilityTimeout: 900, WaitTimeSeconds: 0 })
.promise();
const [message] = response?.Messages || [];
console.log('received message');
if (!message || !message.ReceiptHandle) {
return;
}
// //
// process message here
// //
console.log('Deleting message');
await sqsClient.deleteMessage({ QueueUrl: hydrationCommon.hydrationQueueUrl, ReceiptHandle: message.ReceiptHandle }).promise();
console.log('Finished processing messages');
cron 确保您一次只运行一个 Lambda。这是一种反模式,因为您实际上是在减慢系统速度。但是,它对于某些类型的报告构建或其他密集的数据处理或 ETL 作业来说是有意义的。