Boto3 调用 long-运行 Lambda 运行因 TooManyRequestsException 而中断
Boto3 invocations of long-running Lambda runs break with TooManyRequestsException
使用“long-运行ning”Lambda 的经验
在我的公司,我们最近 运行 进入这种行为,当触发 Lambdas 时,运行 超过 60 秒(boto3 的默认连接建立和读取超时)。
使用 boto3(使用 'InvocationType' 'RequestResponse')调用 Lambda 的美妙之处在于,API returns 相应 Lambda 运行,所以我们想坚持这一点。
问题似乎是,客户端在 API 的常设连接上每分钟触发许多请求。因此,我们尝试了 boto3 client configuration,但增加读取超时会导致在每个超时期限后进行新的(不需要的)调用,而增加连接超时会在 Lambda 完成后触发新的调用。
解决方法
由于对 boto3 的 Lambda 客户端进行的各种调查和实验并未导致使用 'RequestResponse' 调用的工作设置,
我们现在通过使用 Cloudwatch 日志来规避这个问题。为此,必须设置 Lambda 以写入可访问的日志组。然后,可以查询这些日志的状态。然后你会调用 Lambda 并像这样监控它:
import boto3
lambda_client = boto3.client('lambda')
logs_clients = boto3.client('logs')
invocation = lambda_client.invoke(
FunctionName='your_lambda',
InvocationType='Event'
)
# Identifier of the invoked Lambda run
request_id = invocation['ResponseMetadata']['RequestID']
while True:
# filter the logs for the Lambda end event
events = logs_client.filter_log_events(
logGroupName='your_lambda_loggroup',
filterPattern=f'"END RequestId: {request_id}"'
).get('events', [])
if len(events) > 0:
# the Lambda invocation finished
break
这种方法现在对我们有用,但说实话很丑。为了使这种方法稍微好一点,我建议在 filter_log_events 调用中设置时间范围过滤。
一件事,尚未测试(尚未):上述方法仅说明 Lambda 是否终止,但未说明状态(失败或成功),默认日志在这方面没有任何用处。因此,我将调查 Lambda 运行 是否可以在 运行 时间内知道自己的请求 ID。然后 Lambda 代码可以准备好也写入带有请求 ID 的错误消息,然后可以再次对其进行过滤。
使用“long-运行ning”Lambda 的经验
在我的公司,我们最近 运行 进入这种行为,当触发 Lambdas 时,运行 超过 60 秒(boto3 的默认连接建立和读取超时)。
使用 boto3(使用 'InvocationType' 'RequestResponse')调用 Lambda 的美妙之处在于,API returns 相应 Lambda 运行,所以我们想坚持这一点。
问题似乎是,客户端在 API 的常设连接上每分钟触发许多请求。因此,我们尝试了 boto3 client configuration,但增加读取超时会导致在每个超时期限后进行新的(不需要的)调用,而增加连接超时会在 Lambda 完成后触发新的调用。
解决方法
由于对 boto3 的 Lambda 客户端进行的各种调查和实验并未导致使用 'RequestResponse' 调用的工作设置, 我们现在通过使用 Cloudwatch 日志来规避这个问题。为此,必须设置 Lambda 以写入可访问的日志组。然后,可以查询这些日志的状态。然后你会调用 Lambda 并像这样监控它:
import boto3
lambda_client = boto3.client('lambda')
logs_clients = boto3.client('logs')
invocation = lambda_client.invoke(
FunctionName='your_lambda',
InvocationType='Event'
)
# Identifier of the invoked Lambda run
request_id = invocation['ResponseMetadata']['RequestID']
while True:
# filter the logs for the Lambda end event
events = logs_client.filter_log_events(
logGroupName='your_lambda_loggroup',
filterPattern=f'"END RequestId: {request_id}"'
).get('events', [])
if len(events) > 0:
# the Lambda invocation finished
break
这种方法现在对我们有用,但说实话很丑。为了使这种方法稍微好一点,我建议在 filter_log_events 调用中设置时间范围过滤。
一件事,尚未测试(尚未):上述方法仅说明 Lambda 是否终止,但未说明状态(失败或成功),默认日志在这方面没有任何用处。因此,我将调查 Lambda 运行 是否可以在 运行 时间内知道自己的请求 ID。然后 Lambda 代码可以准备好也写入带有请求 ID 的错误消息,然后可以再次对其进行过滤。