使用 Amazon Lambda 函数的最佳实践
以下是推荐使用 Amazon Lambda 的最佳实践:
函数代码
利用执行环境重用来提高函数性能。连接软件开发工具包 (SDK) 客户端和函数处理程序之外的数据库,并在 /tmp 目录中本地缓存静态资产。由函数的同一实例处理的后续调用可重用这些资源。这样就可以通过缩短函数运行时间来节省成本。
为了避免调用之间潜在的数据泄露,请不要使用执行环境来存储用户数据、事件或其他具有安全影响的信息。如果您的函数依赖于无法存储在处理程序的内存中的可变状态,请考虑为每个用户创建单独的函数或单独的函数版本。
使用 keep-alive 指令来维护持久连接。Lambda 会随着时间的推移清除空闲连接。在调用函数时尝试重用空闲连接会导致连接错误。要维护您的持久连接,请使用与运行时关联的 keep-alive 指令。有关示例,请参阅在 Node.js 中通过 Keep-Alive 重用连接。
使用环境变量将操作参数传递给函数。例如,您在写入 Amazon S3 存储桶时,不应对要写入的存储桶名称进行硬编码,而应将存储桶名称配置为环境变量。
避免在 Lambda 函数中使用递归调用,在这种情况下,函数会调用自己或启动可能再次调用该函数的进程。这可能会导致意想不到的函数调用量和升级成本。如果您看到意外的调用量,请立即将函数保留并发设置为 0 来限制对函数的所有调用,同时更新代码。
Lambda 函数代码中不要使用非正式的非公有 API。对于 Amazon Lambda 托管式运行时,Lambda 会定期为 Lambda 的内部 API 应用安全性和功能更新。这些内部 API 更新可能不能向后兼容,会导致意外后果,例如,假设您的函数依赖于这些非公有 API,则调用会失败。请参阅 API 参考以查看公开发布的 API 列表。
编写幂等代码。为您的函数编写幂等代码可确保以相同的方式处理重复事件。您的代码应该正确验证事件并优雅地处理重复事件。有关更多信息,请参阅如何使我的 Lambda 函数具有幂等性?
注意
可使用 Powertools for Amazon Lambda 使函数具有幂等性。有关更多信息,请参阅:
有关特定语言的代码最佳实践,请参阅以下章节:
函数配置
对您的 Lambda 函数进行性能测试是确保选择最佳内存大小配置的关键环节。增加内存大小会触发函数可用 CPU 的同等水平的增加。函数的内存使用率是根据调用情况确定的,可以在 Amazon CloudWatch 中查看。每次调用都将生成一个 REPORT: 条目,如下所示:
REPORT RequestId: 3604209a-e9a3-11e6-939a-754dd98c7be3 Duration: 12.34 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 18 MB
分析 Max Memory Used: 字段能够确定函数是否需要更多内存,或函数的内存大小是否过度配置。
要为您的函数查找适合的内存配置,我们建议使用开源 Amazon Lambda 功率调谐项目。有关更多信息,请参阅 GitHub 上的 Amazon Lambda 功率调谐
为了优化函数性能,我们还建议部署可以利用高级矢量扩展 2 (AVX2) 的库。这样一来,您就可以处理艰巨的工作负载,如机器学习推理、媒体处理、高性能计算(HPC)、科学模拟和财务建模。有关更多信息,请参阅使用 AVX2 创建更快的 Amazon Lambda 函数
对您的 Lambda 函数进行加载测试,确定最佳超时值。分析函数的运行时间很重要,这样更容易确定依赖关系服务是否有问题,这些问题可能导致并发函数以超出您的预期的速度增加。如果您的 Lambda 函数进行网络调用的资源无法处理 Lambda 扩缩,这就更加重要。有关对应用程序进行负载测试的更多信息,请参阅 Amazon 上的分布式负载测试
设置 IAM policy 时使用最严格的权限。了解您的 Lambda 函数所需的资源和操作,并限制这些权限的执行角色。有关更多信息,请参阅在 Amazon Lambda 中管理权限。
熟悉。Lambda 配额在确定运行时资源限制时,负载大小、文件描述符和 /tmp 空间通常会被忽略。
删除不再使用的 Lambda 函数。这样,未使用的函数就不会不必要地占用有限的部署程序包空间。
如果您使用 Amazon Simple Queue Service 作为事件源,请确保该函数的预计调用时间值不超过队列上的可见性超时值。这同样适用于 CreateFunction 和 UpdateFunctionConfiguration。
-
对于 CreateFunction,Amazon Lambda 会使函数创建流程失败。
-
对于 UpdateFunctionConfiguration,它可能会导致该函数的重复调用。
功能可扩展性
熟悉您的上游和下游吞吐量限制。虽然 Lambda 函数可随负载无缝扩展,但上游和下游依赖项可能不具有相同的吞吐量。如果您需要限制函数可以扩展的幅度,可以为函数配置预留并发。
内置节流容错能力:如果同步函数因流量超过 Lambda 的扩展速率而遭遇节流,则可使用以下策略来提高节流容错能力:
-
使用超时、重试和抖动回退
:实施这些策略可以平滑重试的调用,有助于确保 Lambda 可以在几秒钟内纵向扩展,尽量减少最终用户节流。 -
使用预置并发:预置并发是 Lambda 分配给函数的预初始化执行环境的数量。Lambda 在可用时使用预置并发处理传入请求。如有必要,Lambda 还可以将函数扩展到预置并发设置之上。配置预置并发会让 Amazon 账户产生额外费用。
指标和警报
使用 将 CloudWatch 指标与 Lambda 结合使用 和 CloudWatch Alarms,而不是在您的 Lambda 函数代码中创建和更新指标。追踪 Lambda 函数的运行状况是更加有效的方式,这样您就可以在早期开发过程中发现问题。例如,您可以根据 Lambda 函数调用的预计持续时间配置警报,以解决函数代码引起的瓶颈或延迟。
使用嵌入式指标格式 (EMF) 异步发送自定义指标 应使用 EMF 通过函数日志发送指标,而不是对 CloudWatch 进行同步 API 调用。这种方法可减小延迟并改善性能。Powertools for Amazon Lambda 中的指标实用程序可自动处理 EMF 格式。有关更多信息,请参阅“Powertools for Amazon Lambda”文档中的 Python、TypeScript、Java 或 .NET 指标实用程序。有关使用嵌入式指标格式生成指标格式日志的更多信息,请参阅《Amazon CloudWatch 用户指南》中的使用嵌入式指标格式发布日志。
使用结构化的 JSON 日志记录来提高可观测性。结构化日志记录可以更轻松地搜索、筛选和分析函数日志。可考虑使用 Powertools for Amazon Lambda 中的 Logger 实用程序,自动将日志格式化为 JSON。有关更多信息,请参阅“Powertools for Amazon Lambda”文档中的 Python、TypeScript、Java 或 .NET Logger 实用程序。
利用您的日志记录库和 Amazon Lambda 指标和维度捕捉应用程序错误(例如,ERR、ERROR、WARNING 等)
使用 Amazon Cost Anomaly Detection 来检测您账户中的异常活动。Cost Anomaly Detection 使用机器学习技术来持续监控您的成本和使用情况,并尽力减少误报。Cost Anomaly Detection 使用来自 Amazon Cost Explorer 的数据,该数据最长可能会延迟 24 小时。因此,发生使用后最长可能需要 24 小时才会检测到异常。要开始使用 Cost Anomaly Detection,您必须首先注册 Cost Explorer。然后访问 Cost Anomaly Detection。
处理流
测试不同批处理和记录的大小,这样每个事件源的轮询频率都会根据函数完成任务的速度进行调整。CreateEventSourceMapping BatchSize 参数控制每次调用可向您的函数发送记录的最大数量。批处理大小如果较大,通常可以更有效地吸收大量记录的调用开销,从而增加吞吐量。
默认情况下,Lambda 会在记录可用时尽快调用您的函数。如果 Lambda 从事件源中读取的批处理只有一条记录,则 Lambda 将会只向该函数发送一条记录。为避免在记录数量较少的情况下调用该函数,您可以配置 batching window(批处理时段),让事件源缓冲最多五分钟的记录。调用函数前,Lambda 会持续从事件源中读取记录,直到收集完整批处理、批处理时段到期或批处理达到 6MB 的有效负载时为止。有关更多信息,请参阅批处理行为。
警告
Lambda 事件源映射至少处理每个事件一次,有可能出现重复处理记录的情况。为避免与重复事件相关的潜在问题,我们强烈建议您将函数代码设为幂等性。要了解更多信息,请参阅 Amazon 知识中心的如何让我的 Lambda 函数保持幂等性
为流处理启用部分批处理响应。在处理来自 Kinesis 或 DynamoDB 等流的批记录时,启用部分批处理响应,以允许 Lambda 仅重试失败的记录,而非整个批次。这可以提高处理效率并减少不必要的再处理。可选择使用 Powertools for Amazon Lambda 中的批处理实用程序来简化批处理模式。
注意
可使用 Powertools for Amazon Lambda 进行批处理。有关更多信息,请参阅:
通过增加分区提高 Kinesis 流处理吞吐量。一个 Kinesis 流由一个或多个分区组成。Lambda 从 Kinesis 读取数据的速率随着分片数量的增加而线性扩展。增加分区数量会直接增加 Lambda 函数并发调用的最大数量,还可增加 Kinesis 流处理的吞吐量。有关分片和函数调用之间的更多信息,请参阅 轮询和批处理流。如果您增加 Kinesis 流中的分区数量,请确保您已为数据选择了合适的分区键(请参阅分区键),这样相关记录将会位于同一分区中,而且也可合理分配您的数据。
在 IteratorAge 上使用 Amazon CloudWatch,确定是否正在处理您的 Kinesis 流。例如,将 CloudWatch 警报的最大值设置配置为 30000(30 秒)。
安全最佳实践
监控 Amazon Lambda 的使用情况,因为它与使用 Amazon Security Hub CSPM 的安全最佳实践有关。Security Hub 使用安全控件来评估资源配置和安全标准,以帮助您遵守各种合规框架。有关使用 Security Hub 评估 Lambda 资源的更多信息,请参阅《Amazon Security Hub CSPM 用户指南》中的 Amazon Lambda 控件。
使用 Amazon GuardDuty Lambda Protection 监控 Lambda 网络活动日志:在 Amazon Web Services 账户 中调用 Lambda 函数时,GuardDuty Lambda Protection 可帮助识别潜在安全威胁。以某个函数查询与加密货币相关活动关联的 IP 地址为例。GuardDuty 会监控在调用 Lambda 函数时生成的网络活动日志。要了解更多信息,请参阅《Amazon GuardDuty User Guide》中的 Lambda Protection。