如何从 SAM 本地中的另一个 lambda 调用 AWS lambda?

abu*_*ars 6 python boto3 aws-lambda

我正在将 AWS SAM 与 Python 结合使用。我的目标是拥有两个 Lambda:

  • 函数 A:一个普通的同步 Lambda,它将调用函数 B,然后快速返回
  • 函数 B:长时间运行的异步事件 Lambda

还有一些其他 SO 问题可以处理这种情况,但据我所知,没有人涉及在本地部署 SAM 时如何做到这一点。

这是我的 SAM 模板文件:

# template.yaml

Resources:
  FunctionA:
    # PUT /functions/a, should invoke FunctionB asynchronously
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: api/
      Handler: functions.a
      Runtime: python3.7
      Events:
        FunctionA:
          Type: Api
          Properties:
            Path: /functions/a
            Method: put

  FunctionB:
    # Long-running asynchronous function
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: 'FunctionB'
      CodeUri: api/
      Handler: functions.b
      Runtime: python3.7
      EventInvokeConfig:
        MaximumRetryAttempts: 2
        DestinationConfig:
          OnSuccess:
            Type: SQS
          OnFailure:
            Type: SQS
Run Code Online (Sandbox Code Playgroud)

我的 Python lambda 处理程序逻辑:

# template.yaml

Resources:
  FunctionA:
    # PUT /functions/a, should invoke FunctionB asynchronously
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: api/
      Handler: functions.a
      Runtime: python3.7
      Events:
        FunctionA:
          Type: Api
          Properties:
            Path: /functions/a
            Method: put

  FunctionB:
    # Long-running asynchronous function
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: 'FunctionB'
      CodeUri: api/
      Handler: functions.b
      Runtime: python3.7
      EventInvokeConfig:
        MaximumRetryAttempts: 2
        DestinationConfig:
          OnSuccess:
            Type: SQS
          OnFailure:
            Type: SQS
Run Code Online (Sandbox Code Playgroud)

我在本地部署它:

# deploy.sh
sam build
sam local start-api
Run Code Online (Sandbox Code Playgroud)

一切都很好,直到这一点。当我调用 时PUT /functions/a,出现以下错误,表明无法从函数 A 调用函数 B:

[ERROR] ResourceNotFoundException: An error occurred (ResourceNotFoundException) when calling the Invoke operation: Function not found: arn:aws:lambda:us-east-2:[iam-user-id]:function:FunctionB
Run Code Online (Sandbox Code Playgroud)

有没有人找到解决这个问题的方法?这是我尝试过的:

  1. 验证可以通过命令行成功调用函数B:
sam local invoke FunctionB # works great
Run Code Online (Sandbox Code Playgroud)
  1. 尝试更改InvocationType=EventInvocationType=RequestResponse并收到相同的错误
  2. 实例化 lambda 客户端以引用本地 URL
# functions.py

def a(event, context):
  boto3.client('lambda').invoke(
    FunctionName='FunctionB',
    InvocationType='Event',
    Payload='some_data'.encode('UTF-8')
  )
  return { "statusCode": 200, "body": {} }

def b(data):
  print("SUCCESS!")
Run Code Online (Sandbox Code Playgroud)

Arl*_*ess 5

您可以使用sam local start-lambda来运行 FunctionA,它将在端口 3001 上模拟,并使用 lambda 客户端从 FunctionB 调用它:

boto3.client('lambda', endpoint_url='http://docker.for.mac.localhost:3001')

您必须使用,InvocationType=RequestResponse因为尚不支持事件https://github.com/awslabs/aws-sam-cli/pull/749

如果 FunctionB 长时间运行并且因为您只能使用 RequestResponse,您可以更改 lambda 客户端配置以增加超时:

config_lambda = Config(retries={'total_max_attempts': 1}, read_timeout=1200)

lambda_client = boto3.client('lambda',
                             config=config_lambda,
                             endpoint_url='http://docker.for.mac.localhost:3001')
Run Code Online (Sandbox Code Playgroud)