【问题标题】:What is the correct way to write asyncio code for use with AWS Lambda?编写用于 AWS Lambda 的异步代码的正确方法是什么?
【发布时间】:2017-09-21 21:04:15
【问题描述】:

我写了以下代码:


import asyncio

loop = asyncio.get_event_loop()

async def get_urls(event):

    return {'msg':'Hello World'}

def lambda_handler(event,context):

    return loop.run_until_complete(get_urls(event))

我试图以更快的速度完成以下任务。


def lambda_handler(event, context):
    # TODO implement
    return {'msg':'Hello World'}

在 AWS Lambda 环境中编写此代码的正确方法是什么?

【问题讨论】:

  • 你弄明白了吗?

标签: python python-3.x amazon-web-services aws-lambda python-asyncio


【解决方案1】:

为我工作...您需要选择运行时“Python 3.6”或“Python 3.7”。

import asyncio

loop = asyncio.get_event_loop()

async def get_urls(event):
    return {'msg':'Hello World'}

def lambda_handler(event, context):
    return loop.run_until_complete(get_urls(event))

【讨论】:

  • AWS lambda 最佳实践建议“在函数处理程序之外初始化数据库连接”。如何在这样的代码中创建数据库连接?是否可以在函数处理程序之外创建数据库连接?
  • @givo 是的。 Python 在导入期间执行任何“外部代码”(最左边的代码,在任何函数或类之外)。另一种选择是使用全局变量来保存连接并仅在尚未初始化时才在处理函数中对其进行初始化。
  • 感谢@Messa,运行时为我节省了数小时的头痛。
【解决方案2】:

异步执行同时做很多事情。你只做一件事。你不能比做一件事的时间更快地做一件事。异步执行允许您执行通常会一个接一个(同步)同时执行的独立任务,然后返回所有任务的结果。本质上,您必须执行多个操作。

【讨论】:

  • 您是对的,但在某些情况下您可以从 AWS lambda 中的异步中受益。例如,当您的函数聚合来自多个 HTTP 端点的结果时。
【解决方案3】:

对于 Python 3.7+,您可以使用 asyncio.run() 来执行您的协程:

import asyncio

# The AWS Lambda handler
def handler(event, context):
    asyncio.run(main())

async def main():
    # Here you can await any awaitable
    await asyncio.sleep(1)
    await asyncio.gather([coroutine_1, coroutine_2])

下面是一个完整示例,说明如何在 AWS Lambda 上使用 asyncio、aiohttp 和 aiobotocore 开发、测试和部署异步 Python 函数:https://github.com/geeogi/async-python-lambda-template

【讨论】:

  • 我认为这是错误的,至少如果您跨 Lambda 调用重用全局资源。当我使用asyncio.run 时,在后续运行中出现“事件循环关闭”错误。我猜这是因为那些全局资源与之前的事件循环相关联?
【解决方案4】:

需要在本地安装 aioboto3 作为部署 zip 包的一部分 `

import asyncio
import aioboto3



async def list_s3_objs (bucket):
    async with aioboto3.client("s3") as s3_client:
        objs = await s3_client.list_objects(Bucket=bucket)
    return objs['Contents']

def lambda_handler(event, context):
    loop = asyncio.get_event_loop()
    loop.run_until_complete(list_s3_objs('bucket_name'))

`

【讨论】:

    猜你喜欢
    • 2020-04-18
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 2014-12-17
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    相关资源
    最近更新 更多