【发布时间】:2020-02-24 07:37:30
【问题描述】:
我正在使用 python SDK 从另一个 lambda 调用一个 lambda。两个 lambda 都属于同一个 VPC。触发器 lambda 仅包含一个调用第二个 lambda (loader_development) 的 python 脚本,其代码如下:
from __future__ import print_function
import json
import logging
import os
from urllib2 import urlopen,Request,HTTPError
import boto3
logger = logging.getLogger()
logger.setLevel(logging.INFO)
region = os.environ['AWS_REGION']
def lambda_handler(event, context):
logger.info('starting loading')
invokeLambda = boto3.client('lambda', region_name = 'us-east-1')
request = {'resource':'/bucketstatus/latest','path':'/bucketstatus/latest','httpMethod':'GET', 'requestContext': {'requestId': context.aws_request_id,'identity': {'userArn': context.invoked_function_arn}}}
invoke_response = invokeLambda.invoke(FunctionName='loader_development',
InvocationType='RequestResponse',
Payload=json.dumps(request))
print(invoke_response['Payload'].read())
logger.info('Process Complete')
我在上面的代码中遇到了问题。所以我现在面临的问题是这个脚本不止一次触发 loader_development lambda,这会在我的数据库中创建冗余条目(例如:我的数据库中应该只有 6 个条目,但可能是由于多个 lambda 调用导致根据脚本,大约创建了 19 个条目)。
通过分析触发器的 CloudWatch 日志,我了解到它会创建与加载程序 lambda 的 HTTPS 连接并等待响应。如果它没有收到响应,它会再次尝试创建一个新的 HTTPS 连接。我可以在一个日志中看到这三遍。我也贴在这里。
[DEBUG] 2019-10-25T16:00:05.155Z 0342a98d-1cee-474a-9147-b90c4a804c4c Starting new HTTPS connection (1): lambda.us-east-1.amazonaws.com:443
[DEBUG] 2019-10-25T16:01:05.298Z 0342a98d-1cee-474a-9147-b90c4a804c4c Event needs-retry.lambda.Invoke: calling handler <botocore.retryhandler.RetryHandler object at 0x7f8588337b90>
[DEBUG] 2019-10-25T16:01:05.299Z 0342a98d-1cee-474a-9147-b90c4a804c4c retry needed, retryable exception caught: Read timeout on endpoint URL: "https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/loader_development/invocations"
Traceback (most recent call last):
File "/var/runtime/botocore/retryhandler.py", line 269, in _should_retry
return self._checker(attempt_number, response, caught_exception)
File "/var/runtime/botocore/retryhandler.py", line 317, in __call__
caught_exception)
File "/var/runtime/botocore/retryhandler.py", line 223, in __call__
attempt_number, caught_exception)
File "/var/runtime/botocore/retryhandler.py", line 359, in _check_caught_exception
raise caught_exception
ReadTimeoutError: Read timeout on endpoint URL: "https://lambda.us-east-1.amazonaws.com/2015-03-31/functions/loader_development/invocations"
[DEBUG] 2019-10-25T16:01:05.316Z 0342a98d-1cee-474a-9147-b90c4a804c4c Retry needed, action of: 0.421144501955
[DEBUG] 2019-10-25T16:01:05.316Z 0342a98d-1cee-474a-9147-b90c4a804c4c Response received to retry, sleeping for 0.421144501955 seconds
[DEBUG] 2019-10-25T16:01:05.738Z 0342a98d-1cee-474a-9147-b90c4a804c4c Event request-created.lambda.Invoke: calling handler <bound method RequestSigner.handler of <botocore.signers.RequestSigner object at 0x7f8587af6b90>>
[DEBUG] 2019-10-25T16:01:05.738Z 0342a98d-1cee-474a-9147-b90c4a804c4c Event choose-signer.lambda.Invoke: calling handler <function set_operation_specific_signer at 0x7f85887c8398>
上述一组日志在同一日志下出现至少 3 次。我如何告诉脚本不要多次创建 HTTPS 连接,因为这会导致多次调用,并且 loader_development lambda 大部分时间都在忙于尝试处理较旧的请求,因此有时某些实体未成功更新在我的数据库中。请告诉我。谢谢!
更新:我在触发器中添加了以下解决方案,但现在“开始加载”正在打印三次,所以我认为这个脚本被调用了三次。以前只有 loader_development lambda 被重试。(仅供参考:我为触发 cron(0/30 7-9 * * ? *) 启用了 cloudwatch 事件,所以 cloudwatch 事件也有重试机制?)
附:如果我没有计划的 cloudwatch 事件来触发此脚本,则以下解决方案有效。
【问题讨论】:
标签: python-2.7 amazon-web-services aws-lambda boto3