使用boto调用lambda函数我该如何异步执行?

som*_*ode 21 python boto amazon-web-services aws-lambda

所以我正在使用boto来调用我的lambda函数并测试我的后端.我想异步调用它们.我注意到"invoke_async"已弃用,不应使用.相反,您应该使用InvocationType为"Event"的"invoke"来异步执行该函数.

我似乎无法弄清楚如何在函数返回时从函数中获取响应.我尝试过以下方法:

payload3=b"""{
"latitude": 39.5732160891,
"longitude": -119.672918997,
"radius": 100
}"""

client = boto3.client('lambda')
for x in range (0, 5):
    response = client.invoke(
        FunctionName="loadSpotsAroundPoint",
        InvocationType='Event',
        Payload=payload3
    )
    time.sleep(15)
    print(json.loads(response['Payload'].read()))
    print("\n")
Run Code Online (Sandbox Code Playgroud)

即使我告诉代码睡眠15秒,当我尝试打印它时,响应变量仍然是空的.如果我将invokation Invokation类型更改为"RequestResponse",它一切正常并且响应变量打印,但这是同步的.我错过了一些容易的事吗?当async invokation返回时,我如何执行一些代码,例如打印出结果?

谢谢.

Jul*_*ien 21

"异步AWS lambda调用""异步python代码"之间存在差异.当您设置InvocationType'Event',顾名思义,它不会永远发回的响应.

在您的示例中,invoke()立即返回None,并且不会在后台隐式启动任何内容以在以后更改该值(谢天谢地!).所以,当你看response15秒后的值时,它仍然是None.

看起来你真正想要的是RequestResponse调用类型,使用异步Python代码.你有很多选择可供选择,但我最喜欢的是concurrent.futures.另一个是threading.

这是一个使用示例concurrent.futures:

(如果您使用的是Python2,则需要pip install futures)

from concurrent.futures import ThreadPoolExecutor
import json

payload = {...}

with ThreadPoolExecutor(max_workers=5) as executor:
    futs = []
    for x in xrange(0, 5):
        futs.append(
            executor.submit(client.invoke,
                FunctionName   = "loadSpotsAroundPoint",
                InvocationType = "RequestResponse",
                Payload        = bytes(json.dumps(payload))
            )
        )
    results = [ fut.result() for fut in futs ]

print results
Run Code Online (Sandbox Code Playgroud)

您可能想要研究的另一种模式是使用Event调用类型,并让您的Lambda函数将消息推送到SNS,然后由另一个Lambda函数使用.您可以在此处查看SNS触发的lambda函数的教程.

  • 作为后续说明,我不得不使用`bytes(json.dumps(payload),“ utf-8”)`否则会抛出错误 (2认同)

Leo*_*eon 14

异步执行的AWS Lambda函数不会返回执行结果.如果异步调用请求成功(即由于权限等没有错误),AWS Lambda会立即返回HTTP状态代码202 ACCEPTED,并且不再负责传递有关此异步调用结果的任何信息.

AWS Lambda Invoke操作的文档中:

响应语法

HTTP/1.1 StatusCode
X-Amz-Function-Error: FunctionError
X-Amz-Log-Result: LogResult

Payload
Run Code Online (Sandbox Code Playgroud)

响应元素

如果操作成功,则服务将发回以下HTTP响应.

的StatusCode

成功请求的HTTP状态代码将在200范围内.对于RequestResponse调用类型,此状态代码将为200. 对于Event调用类型,此状态代码将为202.对于DryRun调用类型,状态代码将为204.

[...]

响应将以下内容作为HTTP正文返回.

有效载荷

它是Lambda函数返回的对象的JSON表示形式.仅当调用类型为时,才会出现此情况 RequestResponse.


yle*_*lev 14

以下是接受 lambda-function-Name 调用和有效载荷发送到该函数的 python 函数。

它通过 boto3 客户端调用 lambda 函数。

import boto3, json, typing

def invokeLambdaFunction(*, functionName:str=None, payload:typing.Mapping[str, str]=None):
    if  functionName == None:
        raise Exception('ERROR: functionName parameter cannot be NULL')
    payloadStr = json.dumps(payload)
    payloadBytesArr = bytes(payloadStr, encoding='utf8')
    client = boto3.client('lambda')
    response = client.invoke(
        FunctionName=functionName,
        InvocationType="RequestResponse",
        Payload=payloadBytesArr
    )
    return response
Run Code Online (Sandbox Code Playgroud)

和用法:

if __name__ == '__main__':
    payloadObj = {"something" : "1111111-222222-333333-bba8-1111111"}
    response = invokeLambdaFunction(functionName='myLambdaFuncName',  payload=payloadObj
    print(f'response:{response}')
Run Code Online (Sandbox Code Playgroud)

  • 获取输出:`response["Payload"].read()` (2认同)