AWS Lambda Web 适配器
一个在 AWS Lambda 上运行 Web 应用程序的工具
AWS Lambda Web 适配器允许开发人员使用熟悉的框架(如 Express.js、Next.js、Flask、SpringBoot、ASP.NET 和 Laravel,任何支持 HTTP 1.1/1.0 的框架)构建 Web 应用程序(HTTP API),并在 AWS Lambda 上运行。 同一个 Docker 镜像可以在 AWS Lambda、Amazon EC2、AWS Fargate 和本地计算机上运行。
特性
- 在 AWS Lambda 上运行 Web 应用程序
- 支持 Amazon API Gateway Rest API 和 Http API 端点、Lambda 函数 URL 和应用程序负载均衡器
- 支持 Lambda 托管运行时、自定义运行时和 Docker OCI 镜像
- 支持任何 Web 框架和语言,无需包含新的代码依赖
- 自动编码二进制响应
- 启用优雅关闭
- 支持响应负载压缩
- 支持响应流式传输
- 支持非 HTTP 事件触发器
使用方法
AWS Lambda Web 适配器可以与打包为 Docker 镜像和 Zip 包的 Lambda 函数一起使用。
打包为 Docker 镜像或 OCI 镜像的 Lambda 函数
要在 Docker 镜像中使用 Lambda Web 适配器,请在 Dockerfile 中打包您的 Web 应用程序(HTTP API),并添加一行代码将 Lambda Web 适配器二进制文件复制到容器内的 /opt/extensions:
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter
可以使用非 AWS 基础镜像,因为运行时接口客户端随 Lambda Web 适配器一起提供。
默认情况下,Lambda Web 适配器假设 Web 应用程序在端口 8080 上监听。如果不是,您可以通过配置指定端口。
预编译的 Lambda Web 适配器二进制文件在 ECR 公共仓库中提供:public.ecr.aws/awsguru/aws-lambda-adapter。 该仓库还提供多架构镜像。它适用于 x86_64 和 arm64 CPU 架构。
以下是一个示例 Node.js 应用程序的 Dockerfile。
FROM public.ecr.aws/docker/library/node:20-slim
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.8.4 /lambda-adapter /opt/extensions/lambda-adapter
ENV PORT=7000
WORKDIR "/var/task"
ADD src/package.json /var/task/package.json
ADD src/package-lock.json /var/task/package-lock.json
RUN npm install --omit=dev
ADD src/ /var/task
CMD ["node", "index.js"]
这适用于除 AWS 托管基础镜像之外的任何基础镜像。要使用 AWS 托管基础镜像,您需要覆盖 ENTRYPOINT 以启动您的 Web 应用程序。
打包为 Zip 包的 AWS 托管运行时 Lambda 函数
AWS Lambda Web 适配器也适用于 AWS 托管 Lambda 运行时。您需要执行以下三个步骤:
-
将 Lambda Web 适配器层附加到您的函数。
AWS 商业区域
- x86_64:
arn:aws:lambda:${AWS::Region}:753240598075:layer:LambdaAdapterLayerX86:23
- arm64:
arn:aws:lambda:${AWS::Region}:753240598075:layer:LambdaAdapterLayerArm64:23
AWS 中国区域
- cn-north-1(北京)
- x86_64:
arn:aws-cn:lambda:cn-north-1:041581134020:layer:LambdaAdapterLayerX86:23
- x86_64:
- cn-northwest-1(宁夏)
- x86_64:
arn:aws-cn:lambda:cn-northwest-1:069767869989:layer:LambdaAdapterLayerX86:23
- x86_64:
- x86_64:
-
将 Lambda 环境变量
AWS_LAMBDA_EXEC_WRAPPER
配置为/opt/bootstrap
。 -
将函数处理程序设置为您的 Web 应用程序启动脚本。例如:
run.sh
。
详细信息请查看示例 Node.js 应用程序。
就绪检查
当新的 Lambda 执行环境启动时,Lambda Web 适配器将作为 Lambda 扩展启动,然后启动 Web 应用程序。
默认情况下,Lambda Web 适配器将向 Web 应用程序发送 HTTP GET 请求,地址为 http://127.0.0.1:8080/
。可以通过两个环境变量自定义端口和路径:AWS_LWA_READINESS_CHECK_PORT
和 AWS_LWA_READINESS_CHECK_PATH
。
Lambda Web 适配器将每 10 毫秒重试此请求,直到 Web 应用程序返回 HTTP 响应(状态码 >= 100 且 < 500)或函数超时。
此外,您可以通过将 AWS_LWA_READINESS_CHECK_PROTOCOL
设置为 tcp
,将适配器配置为使用 TCP 连接执行就绪检查。
通过就绪检查后,Lambda Web 适配器将启动 Lambda 运行时并将调用转发到 Web 应用程序。
配置
可以使用环境变量配置就绪检查端口/路径和流量端口。这些环境变量可以在 Docker 文件中定义,也可以作为 Lambda 函数配置定义。
环境变量 | 描述 | 默认值 |
---|---|---|
AWS_LWA_PORT / PORT* | 流量端口 | "8080" |
AWS_LWA_READINESS_CHECK_PORT / READINESS_CHECK_PORT* | 就绪检查端口,默认为流量端口 | PORT |
AWS_LWA_READINESS_CHECK_PATH / READINESS_CHECK_PATH* | 就绪检查路径 | "/" |
AWS_LWA_READINESS_CHECK_PROTOCOL / READINESS_CHECK_PROTOCOL* | 就绪检查协议:"http" 或 "tcp",默认为 "http" | "http" |
AWS_LWA_READINESS_CHECK_MIN_UNHEALTHY_STATUS | 被视为不健康的最小 HTTP 状态码 | "500" |
AWS_LWA_ASYNC_INIT / ASYNC_INIT* | 为长初始化函数启用异步初始化 | "false" |
AWS_LWA_REMOVE_BASE_PATH / REMOVE_BASE_PATH* | 从请求路径中移除的基本路径 | 无 |
AWS_LWA_ENABLE_COMPRESSION | 启用响应体的 gzip 压缩 | "false" |
AWS_LWA_INVOKE_MODE | Lambda 函数调用模式:"buffered" 或 "response_stream",默认为 "buffered" | "buffered" |
AWS_LWA_PASS_THROUGH_PATH | 接收从非 HTTP 触发器传递的事件负载的路径 | "/events" |
AWS_LWA_AUTHORIZATION_SOURCE | 要替换为 Authorization 的头部名称 | 无 |
注意: 我们使用 "AWS_LWA_" 前缀来命名 Lambda Web 适配器使用的所有环境变量。原始变量名将继续支持,直到我们达到 1.0 版本。
AWS_LWA_PORT / PORT - Lambda Web 适配器将流量发送到此端口。这是您的 Web 应用程序监听的端口。在 Lambda 执行环境中,Web 应用程序以非 root 用户身份运行,不允许监听低于 1024 的端口。请同时避免使用端口 9001 和 3000。Lambda 运行时 API 在端口 9001 上。CloudWatch Lambda Insight 扩展使用端口 3000。
AWS_LWA_ASYNC_INIT / ASYNC_INIT - Lambda 托管运行时为函数初始化提供最多 10 秒的时间。在此期间,Lambda 函数具有突发 CPU 以加速初始化,且是免费的。如果 Lambda 函数无法在 10 秒内完成初始化,Lambda 将重新启动该函数,并对初始化计费。为了帮助函数利用这 10 秒的免费初始化时间并避免重新启动,Lambda Web 适配器支持异步初始化。启用此功能后,Lambda Web 适配器将执行长达 9.8 秒的就绪检查。如果 Web 应用程序在此之前未就绪,Lambda Web 适配器会向 Lambda 服务发送信号表示初始化已完成,并在处理程序中继续进行就绪检查。默认情况下,此功能处于禁用状态。通过将环境变量 AWS_LWA_ASYNC_INIT
设置为 true
来启用它。
AWS_LWA_REMOVE_BASE_PATH / REMOVE_BASE_PATH - 此环境变量的值告诉适配器应用程序是否在基本路径下运行。例如,您可能已将 API Gateway 配置为具有 /orders/{proxy+} 和 /catalog/{proxy+} 资源。每个资源由单独的 Lambda 函数处理。因此,Lambda 内部的应用程序可能不知道 /orders 路径的存在。使用 REMOVE_BASE_PATH 在将请求路由到应用程序时删除 /orders 前缀。默认为空字符串。查看 SpringBoot 示例。
AWS_LWA_ENABLE_COMPRESSION - Lambda Web 适配器支持响应体的 gzip 压缩。默认情况下,此功能处于禁用状态。通过将环境变量 AWS_LWA_ENABLE_COMPRESSION
设置为 true
来启用它。启用后,除非响应是由内容类型以 image
开头确定的图像,或响应小于 32 字节,否则将压缩响应。这还将压缩 HTTP/1.1 分块流式响应。
AWS_LWA_INVOKE_MODE - Lambda 函数调用模式,这应与函数 URL 调用模式匹配。默认为 "buffered"。当配置为 "response_stream" 时,Lambda Web 适配器将向 Lambda 服务流式传输响应 博客。请查看 FastAPI 与响应流式传输 示例。
AWS_LWA_READINESS_CHECK_MIN_UNHEALTHY_STATUS - 允许您自定义哪些 HTTP 状态码被视为健康,哪些被视为不健康
AWS_LWA_PASS_THROUGH_PATH - 接收从非 HTTP 事件触发器传递的事件负载的路径。默认为 "/events"。
AWS_LWA_AUTHORIZATION_SOURCE - 设置后,Lambda Web 适配器会在代理请求之前将指定的头部名称替换为 Authorization
。当您使用 IAM 身份验证类型 的 Lambda 函数 URL 时,这很有用,因为它为 IAM 身份验证保留了 Authorization 头部,但您仍然希望为后端应用程序使用 Authorization 头部。默认情况下,此功能处于禁用状态。
请求上下文
请求上下文是 API Gateway 为请求发送给 Lambda 的元数据。它通常包含 requestId、requestTime、apiId、identity 和 authorizer。Identity 和 authorizer 对于获取客户端身份以进行授权很有用。API Gateway 开发者指南在此处包含更多详细信息。
Lambda Web 适配器将此信息以名为 "x-amzn-request-context" 的 HTTP 头部转发给 Web 应用程序。在 Web 应用程序中,您可以检索此 HTTP 头部的值并将其反序列化为 JSON 对象。查看 Express.js in Zip 了解如何使用它。
Lambda 上下文
Lambda 上下文是 Lambda 传递给函数处理程序的对象。此对象提供有关调用、函数和执行环境的信息。您可以在此处找到通过 Lambda 上下文可访问的属性的完整列表。 Lambda Web Adapter 将此信息通过名为 "x-amzn-lambda-context" 的 HTTP 头转发给 Web 应用程序。在 Web 应用程序中,您可以获取此 HTTP 头的值并将其反序列化为 JSON 对象。查看 ZIP 格式的 Express.js 了解如何使用它。
优雅关闭
对于注册了 Lambda 扩展的函数,Lambda 为该函数启用了关闭阶段。当 Lambda 服务即将关闭 Lambda 执行环境时,它会向运行时发送 SIGTERM 信号,然后向每个已注册的外部扩展发送 SHUTDOWN 事件。开发人员可以在 Lambda 函数中捕获 SIGTERM 信号并执行优雅关闭任务。Express.js 提供了一个简单的示例。更多详情请参阅此仓库。
本地调试
Lambda Web Adapter 允许开发人员使用熟悉的工具和调试器在本地开发 Web 应用程序:只需在本地运行 Web 应用程序并进行测试。如果您想在本地模拟 Lambda 运行时环境,可以使用 AWS SAM CLI。以下命令启动本地 API Gateway 端点并模拟 Lambda 运行时执行环境。
sam local start-api
请注意,sam local
在端口 8080 上启动 Lambda 运行时接口模拟器。因此,如果您计划使用 sam local
,您的 Web 应用程序应避免使用端口 8080
。
非 HTTP 事件触发器
Lambda Web Adapter 还支持所有非 HTTP 事件触发器,如 SQS、SNS、S3、DynamoDB、Kinesis、Kafka、EventBridge 和 Bedrock Agents。适配器通过 HTTP POST 将事件负载转发到由 AWS_LWA_PASS_THROUGH_PATH
环境变量定义的路径。默认情况下,此路径设置为 /events
。Web 应用程序从请求体接收事件负载后,应处理它并以 JSON 响应的形式返回结果。请查看 SQS Express.js 和 ZIP 格式的 Bedrock Agent FastAPI 示例。
示例
- FastAPI
- ZIP 格式的 FastAPI
- 带后台任务的 FastAPI
- 带响应流的 FastAPI
- ZIP 格式的带响应流的 FastAPI
- Flask
- ZIP 格式的 Flask
- 无服务器 Django 由 @efi-mk 提供
- Express.js
- ZIP 格式的 Express.js
- Next.js
- ZIP 格式的 Next.js
- Next.js 响应流
- SpringBoot
- ZIP 格式的 SpringBoot
- SpringBoot 响应流
- Nginx
- PHP
- ZIP 格式的 Rust Actix Web
- ZIP 格式的 Rust Axum
- Golang Gin
- ZIP 格式的 Golang Gin
- ZIP 格式的 Deno Oak
- Lambda 上的 Laravel
- ASP.NET MVC
- ZIP 格式的 ASP.NET MVC
- ZIP 格式的 ASP.NET Web API
- SQS Express.js
- Bedrock Agent FastAPI
- ZIP 格式的 Bedrock Agent FastAPI
致谢
本项目受到了几个社区项目的启发。
类似项目
几个项目也提供了类似的功能,作为特定语言的包/框架。
- Serverless Java Container
- Serverless Express
- Serverless Python - Zappa
- Serverless Rails - Lamby
- Serverless PHP - Bref
安全
有关更多信息,请参阅 CONTRIBUTING。
许可证
本项目采用 Apache-2.0 许可证。