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