【发布时间】:2019-09-21 07:20:42
【问题描述】:
我的 SQS 应该触发一次 Lambda 函数。好像反复触发,找不到原因。
系统的工作原理如下:
文件已上传到 S3 存储桶(我们称之为
uploaded-docs)。将文件上传到
uploaded-docs/input/会触发存储桶上的一个事件,称为FileUploaded。事件
FileUploaded触发一个名为ProcessUploadedFile的 Lambda 函数。ProcessUploadeFile调用 Textract 来分析文档。所述 Textract 过程的输出(完成后)发布到名为TextractComplete的 SNS 主题。TextractComplete有一个订阅,名为TextractOutputQueue的 SQS。TextractOutputQueue触发一个名为GetOutput的 Lambda 函数。每个上传的文件只应该运行一次
我注意到,当一个文件被上传时,GetOutput 被一遍又一遍地调用在文件上,Task timed out after 3 seconds(Textract 的GetDocumentTextDetection 命令通过boto3 调用)可以在日志中找到,直到它最终超过。
我还注意到,当一个新文件被上传时,桶中的所有文件都会在这个过程中再次调用。
一些假设:
-
SQS 队列项没有被“消费”,因此它们在调用各自的 Lambda 函数后仍然存在于队列中,并且因为它们仍然存在,所以它们会继续调用该函数。
Lambda
GetOutput卡在某种重试循环中,每次超时,它都会再次调用整个函数。这并不能解释为什么在我上传另一个文档之前日志会死掉,并且之前上传的所有文档都会以某种方式再次进入循环。
【问题讨论】:
-
“任务在 3 秒后超时”听起来像是原因。由于 Lambda 没有成功处理请求,它被添加回队列并重试。
-
如果您的进程耗时超过 3 秒,则需要增加 lambda 函数的超时时间。您可以在 lambda 函数的控制台中执行此操作。
-
我建议检查用 GetOutput lambda 函数编写的代码。尝试增加 GetOutput lambda 超时(默认 3 秒)并查看该函数是否需要更多时间空间来完成该功能?当 Lambda 从队列中读取消息时,它会保留在队列中,但会隐藏,直到 Lambda 将其删除。如果您的函数返回错误,或者在队列的可见性超时之前未完成处理,则它会再次可见。然后 Lambda 再次将其发送到您的 Lambda 函数。失败批次中的所有消息都返回队列。查询什么是 SQS 的消息保留期。
标签: python-3.x amazon-web-services aws-lambda amazon-sqs