减少 AWS API Gateway + Lambda 上超过 30 秒的冷启动时间

问题描述 投票:0回答:1

与 API 网关一起部署在 Docker 容器中的 Lambda 函数一直面临着极其缓慢的冷启动。

技术堆栈:

为了进行部署,我一直使用 AWS SAM 和以下模板文件:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  demo

Resources:
  AppFunction:
    Type: AWS::Serverless::Function
    Properties:
      Timeout: 118
      MemorySize: 3008
      CodeUri: app/
      PackageType: Image
      Events:
        ApiEvent:
          Properties:
              RestApiId:
                  Ref: FastapiExampleGateway
              Path: /{proxy+}
              Method: ANY
              Auth:
                ApiKeyRequired: true
          Type: Api
    Metadata:
      Dockerfile: Dockerfile
      DockerContext: .
      
  FastapiExampleGateway:
    Type: AWS::Serverless::Api
    Properties:
        StageName: prod
        OpenApiVersion: '3.0.0'
        # Timeout: 30
    Auth:
      ApiKeyRequired: true
      UsagePlan:
        CreateUsagePlan: PER_API
        UsagePlanName: GatewayAuthorization

Outputs:
  Api:
    Description: "API Gateway endpoint URL for Prod stage for App function"
    Value: !Sub "https://${FastapiExampleGateway}.execute-api.${AWS::Region}.amazonaws.com/Prod/"

lambda相对较轻,安装时需要满足以下要求:

jsonschema==4.16.0
numpy==1.23.3
pandas==1.5.0
pandas-gbq==0.17.8
fastapi==0.87.0
uvicorn==0.19.0
PyYAML==6.0
SQLAlchemy==1.4.41
pymongo==4.3.2
google-api-core==2.10.1
google-auth==2.11.0
google-auth-oauthlib==0.5.3
google-cloud-bigquery==3.3.2
google-cloud-bigquery-storage==2.16.0
google-cloud-core==2.3.2
google-crc32c==1.5.0
google-resumable-media==2.3.3
googleapis-common-protos==1.56.4
mangum==0.11.0

我用于部署的 Dockerfile 是:

FROM public.ecr.aws/lambda/python:3.9

WORKDIR /code

RUN pip install pip --upgrade

COPY ./api/requirements.txt /code/api/requirements.txt

RUN pip install --no-cache-dir -r /code/api/requirements.txt

COPY ./api /code/api

EXPOSE 7777

CMD ["api.main.handler"]

ENV PYTHONPATH "${PYTHONPATH}:/code/"

导致 250mb 的图像。

在第一次 Lambda 拉取时,我看到了 this time before launch

看起来在实际的 lambda 执行之前有一个很长的开始。由于最长响应时间为 30 秒,API 网关已经超时!

  • 使用
    sam local start-api
    进行本地测试效果很好。
  • 我尝试将 lambda 函数 RAM 增加到更高的值。

不确定这是否是 Mangum(FastAPI 的包装)的问题?

aws-lambda aws-api-gateway fastapi aws-sam
1个回答
0
投票

我对容器支持的 Lambda 的体验与您相同。对于 1GB 容器,我的初始化时间可能是 5-20 秒。每个库导入的时间大约是我个人机器上的 10 倍,即使分配了最大内存(以及 CPU)。

这里有一篇来自 AWS Lambda 工程师的博客文章 https://brooker.co.za/blog/2023/05/23/snapshot-loading.html 解释了 AWS 从 S3 延迟加载整个容器文件系统。这意味着实际的冷启动时间比综合测试中出现的时间要糟糕得多(例如 mikhail.io/serverless/coldstarts/aws 上的博客文章),因为它们可能“使用”5GB 容器,但我强烈怀疑它们不要碰其中的任何文件。

Lambda 对图像使用的多级缓存也使得测试这些内容变得困难。因为虽然日志会告诉您是否进行了冷启动(“init”时间),但它并没有告诉您它是从哪个 Lambda 缓存中提取的(可能是三者的混合)。当某个功能在 6 小时内没有使用时,我可能会得到 2-5 秒的冷启动时间。但当一周没有使用时,我会得到 10-20 秒的冷启动时间。

这一切都非常令人失望。结果是,您本质上必须对面向客户端的任何事情使用预配置并发。

© www.soinside.com 2019 - 2024. All rights reserved.