将响应发送回客户端时,AWS lambda 未完成执行

AWS lambda does not finish execution when response is sent back to client

我正在尝试使用 FastAPI 实现即发即弃机制。我在实施该机制时遇到了一些困难。

我有两个应用程序。一种是用 FastAPI 开发的,另一种是 Flask。 FastAPI 将在 AWS Lambda 中 运行 并将请求发送到 运行ning 在 AWS ECS.

目前,我能够向 Flask API 发送请求并从 FastAPI 应用程序收到即时响应。但是我在后台看到 FastAPI 仍然 运行ning bg_tasks.add_task(make_request, request),它在 lambda 执行阈值时间(15 分钟)后超时。

快速API应用程序:


def make_request(data):
    """
    Function to make a post request to flask application
    :param data: Data from the user to write into the file
    :return: None
    """

    print("***** Inside post *****")

    requests.post(url=root_url, data=data)

    print("***** Post completed *****")


@router.post("/write-to-file")
async def write_to_file(request: Dict, bg_tasks: BackgroundTasks):
    """
    Function to queue the requests and return to the post function
    :param request: Request from the user
    :param bg_tasks: Background task instance
    :return: Some message
    """

    print(f"****** Request call started ******")

    bg_tasks.add_task(make_request, request)

    print(f"****** Request completed ******")

    return {"Message": "Data will be written into the file"}

烧瓶应用程序:

@app.route('/', methods=['POST'])
def write():
    """
    Function to write the request data into the file
    :return:
    """
    request_data = request.form
    try:
        print(f"Sleep time {int(request_data['sleep_time'])}")
        time.sleep(int(request_data["sleep_time"]))
        request_data = dict(request_data)
        request_data['current_time'] = str(datetime.now())
        with open("data.txt", "a") as f:
            f.write("\n")
            f.write(json.dumps(request_data, indent=4))

        return {"Message": "Success"}

    except Exception as e:
        return {"Message": e}

Fast API (http://localhost:8000/write-to-file/) 调用 write_to_file 方法,它添加了所有任务(请求)进入后台队列并 运行 在后台发送它们。

此函数不等待进程完成。但是,它 returns 对客户端的响应。 make_request 方法将触发 Flask 端点 (http://localhost:5000/),后者将处理请求并写入文件。将 make_request 视为一个 AWS lambda,如果 flask 应用程序需要更多时间来处理,lambda 将等待更长的时间。

是否可以在请求发布后终止 lambda,或者采取其他措施来解决超时问题?

使用当前设置,只要 Flask 端点需要处理您的请求,您的 lambda 就会 运行。实际上,两个 APIs 运行 完全相同。

这是因为lambda函数中的requests.post必须等待响应完成。鉴于你不关心那个响应的结果,我可以想出其他几种方法来解决这个问题。

如果我是你,我会把队列处理移到ECS端。然后,lambda 唯一负责将作业放入 ECS worker 在有容量时将处理的队列中。

此选项可让您摆脱其中一个 API:您将能够直接查询 Flask API 并终止 lambda 函数,或者改为终止 Flask API 和 运行 ECS 上的工作进程。

或者,您可以 respond early 在 Flask API 端,这将完成您的 HTTP 请求,从而更快地执行 lambda。这可能会使设置变得混乱,并且首先会破坏公开 HTTP API 的目的。此外,在某些情况下,Flask 请求执行可能会在默认超时(~30 秒)后被网络服务器终止。

最后,如果您真的非常想保留您现在的代码,您可以在短时间后设置 request to timeout。如果你走这条路,请确保选择足够长的超时时间让 Flask 开始处理请求:

try:
    requests.post(url=root_url, data=data, timeout=5) # throw after 5 seconds of waiting
except requests.exceptions.Timeout:
    pass