使用 Node.js 构建 Lambda 函数 - AWS Lambda

使用 Node.js 构建 Lambda 函数

您可以使用 Node.js 在 AWS Lambda 中运行 JavaScript 代码。Lambda 可为 Node.js 提供运行时,用于运行代码来处理事件。您的代码在包含 AWS SDK for JavaScript 的环境中运行,其中包含来自您管理的 AWS Identity and Access Management (IAM) 角色的凭证。要了解有关 Node.js 运行时随附的 SDK 版本的更多信息,请参阅 包含运行时的 SDK 版本

Lambda 支持以下 Node.js 运行时。

名称 标识符 操作系统 弃用日期 阻止函数创建 阻止函数更新

Node.js 20

nodejs20.x

Amazon Linux 2023

未计划

未计划

未计划

Node.js 18

nodejs18.x

Amazon Linux 2

2025 年 7 月 31 日

2025 年 9 月 1 日

2025 年 10 月 1 日

注意

Node.js 18 和更高版本运行时系统使用适用于 JavaScript v3 的 AWS SDK。要从较早的运行时系统迁移函数,请关注 GitHub 上的 migration workshop(迁移研讨会)。有关适用于 JavaScript 版本 3 的 AWS SDK的更多信息,请参阅适用于 JavaScript 的模块化 AWS SDK 现已正式发布博客文章。

创建 Node.js 函数
  1. 打开 Lambda 控制台

  2. 选择 Create function(创建函数)。

  3. 配置以下设置:

    • 函数名称:输入函数名称。

    • 运行时系统:选择 Node.js 20.x

  4. 选择 Create function(创建函数)。

  5. 要配置测试事件,请选择测试

  6. 对于事件名称,输入 test

  7. 选择 Save changes(保存更改)。

  8. 要调用该函数,请选择 Test(测试)。

控制台使用名为 index.jsindex.mjs 的单个源文件创建一个 Lambda 函数。您可以在内置代码编辑器中编辑此文件并添加更多文件。要保存您的更改,请选择 Save(保存)。然后,要运行代码,请选择 Test(测试)。

index.jsindex.mjs 文件会导出一个名为 handler 的函数,此函数将接受事件对象和上下文对象。这是 Lambda 在调用函数时调用的处理函数。Node.js 函数运行时从 Lambda 获取调用事件并将其传递到处理程序。在函数配置中,处理程序值为 index.handler

保存函数代码时,Lambda 控制台会创建一个 .zip 文件归档部署包。在控制台外部开发函数代码时(使用 IDE),您需要创建部署程序包将代码上载到 Lambda 函数。

除了调用事件之外,函数运行时还将上下文对象传递给处理程序。上下文对象包含有关调用、函数和执行环境的其他信息。环境变量中提供了更多信息。

您的 Lambda 函数附带了 CloudWatch Logs 日志组。函数运行时会将每次调用的详细信息发送到 CloudWatch Logs。该运行时会中继调用期间函数输出的任何日志。如果您的函数返回错误,则 Lambda 将为错误设置格式,并将其返回给调用方。

Node.js 初始化

Node.js 使用独有的事件循环模型,导致其初始化行为与其他运行时不同。具体来说,Node.js 使用支持异步操作的非阻止式 I/O 模型。此模型允许 Node.js 高效地执行大多数工作负载。例如,假设 Node.js 函数进行网络调用,则该请求可能会被指定为异步操作并放入回调队列中。函数可能会继续处理主调用堆栈内的其他操作,而不会因等待网络调用返回而被阻止。完成网络调用后,将会执行对它的回调,然后从回调队列中删除。

某些初始化任务可能会异步运行。这些异步任务不能保证在调用之前完成执行。例如,在 Lambda 执行处理函数时,进行网络调用以从 AWS 参数存储中获取参数的代码可能尚未完成。因此在调用过程中,变量可能为空。为避免这种情况,请首先确保变量和其他异步代码已完全初始化,然后再继续使用函数的其余核心业务逻辑。

或者,您可以将函数代码指定为 ES 模块,以便在函数处理程序的范围之外,在文件的最顶层使用 await。当您 await 每个 Promise 时,异步初始化代码会在处理程序调用之前完成,从而最大限度地提高预置并发在减少冷启动延迟方面的有效性。有关更多信息和示例,请参阅在 AWS Lambda 中使用 Node.js ES 模块和顶级等待

将函数处理程序指定为 ES 模块

默认情况下,Lambda 将带有 .js 后缀的文件视为 CommonJS 模块。或者,您可以将您的代码指定为 ES 模块。您可以通过两种方式执行此操作:在函数的 package.json 文件中将 type 指定为 module,或者使用 .mjs 文件扩展名。在第一种方式中,函数代码将所有 .js 文件视为 ES 模块,而在第二种场景中,只有使用 .mjs 指定的文件才是 ES 模块。您可以通过将它们分别命名为 .mjs.cjs 来混合 ES 模块和 CommonJS 模块,因为 .mjs 文件始终是 ES 模块,.cjs 文件始终是 CommonJS 模块。

Lambda 会在加载 ES 模块时在 NODE_PATH 环境变量中搜索文件夹。您可以使用 ES 模块 import 语句加载运行时中包含的 AWS SDK。您也可以从加载 ES 模块。

包含运行时的 SDK 版本

Node.js 运行时中包含的 AWS SDK 版本取决于运行时版本和您的 AWS 区域。要查找您正在使用的运行时中包含的 SDK 的版本,请使用以下代码创建 Lambda 函数。

注意

下面显示的 Node.js 版本 18 及以上版本的示例代码使用 CommonJS 格式。如果您在 Lambda 控制台中创建函数,则请务必将包含代码的文件重命名为 index.js

例 Node.js 18 及更高版本
const { version } = require("@aws-sdk/client-s3/package.json"); exports.handler = async () => ({ version });

这会返回以下格式的响应:

{ "version": "3.462.0" }

对 TCP 连接使用“保持连接”

默认的 Node.js HTTP/HTTPS 代理会为每个新请求创建一个新的 TCP 连接。为了避免建立新连接的成本,您可以使用 keepAlive: true 来重用函数使用适用于 JavaScript 的 AWS SDK 创建的连接。“保持连接”可以减少使用 SDK 进行多次 API 调用的 Lambda 函数的请求时间。

在适用于 JavaScript 的 AWS SDK 版本 3.x(包含在 nodejs18.x 和更高版本的 Lambda 运行时系统中)中,默认启用“保持连接”。要禁用“保持连接”,请参阅《AWS SDK for JavaScript 3.x Developer Guide》中的 Reusing connections with keep-alive in Node.js。有关使用“保持连接”的更多信息,请参阅 AWS 开发工具博客上的 HTTP keep-alive is on by default in modular AWS SDK for JavaScript

正在加载 CA 证书

对于 Node.js 18 之前的 Node.js 运行时系统版本,Lambda 会自动加载特定于 Amazon 的 CA(证书颁发机构)证书,让您更轻松地创建与其他 AWS 服务交互的函数。例如,Lambda 包括验证安装在 Amazon RDS 数据库上的服务器身份证书所必需的 Amazon RDS 证书。这种行为可能会对冷启动期间的性能产生影响。

从 Node.js 20 开始,Lambda 默认不再加载其他 CA 证书。Node.js 20 运行时系统包含一个证书文件,其中所有 Amazon CA 证书都位于 /var/runtime/ca-cert.pem。要从 Node.js 18 及更早版本的运行时系统恢复相同的行为,请将 NODE_EXTRA_CA_CERTS 环境变量设置为 /var/runtime/ca-cert.pem

为了获得最佳性能,我们建议仅将所需的证书与部署包捆绑在一起,并通过 NODE_EXTRA_CA_CERTS 环境变量进行加载。证书文件应包含一个或多个 PEM 格式的可信根证书或中间 CA 证书。例如,对于 RDS,将所需的证书与代码一起包含在 certificates/rds.pem。然后,通过将 NODE_EXTRA_CA_CERTS 设置为 /var/task/certificates/rds.pem 来加载证书。