如何排查 Lambda 函数调用超时错误?
我的 AWS Lambda 函数间歇性超时,即便我没有部署任何代码更改。如何排查和防止 Lambda 函数调用超时问题?
解决方法
Lambda 函数可能会因多种原因超时。要排查 Lambda 函数超时,请首先使用本文中列出的一项 AWS 服务和功能来确定导致错误的原因。然后,根据您的使用案例修复问题。
为了帮助防止 Lambda 函数超时,请参阅本文的防止 Lambda 函数超时的最佳实践。
验证您的 Lambda 函数是否超时
通过搜索函数的 Amazon CloudWatch 日志组中的短语 Task timed out(任务超时)来检索任何超时调用的请求 ID。然后,使用关联超时调用的请求 ID,接收每个调用超时的完整日志。
有关说明,请参阅如何确定我的 Lambda 函数是否超时?
确定导致 Lambda 函数超时的原因
使用以下其中一种或多种方法来确定导致函数超时的故障点:
查看 Lambda 的 CloudWatch Logs
您可以使用 Amazon CloudWatch 查看由函数代码生成的所有日志,并识别潜在问题。有关说明,请参阅访问 Lambda 的 CloudWatch Logs。
如果您的函数返回堆栈跟踪,则堆栈跟踪中的错误消息会指出错误原因。
重要提示:Lambda 将会自动为每个调用生成三行日志(START、END 和 REPORT)。如果以下任意一项为 true,则函数的 CloudWatch 日志中将仅显示这三行:
- Lambda 函数的自定义代码中没有配置任何其他显式日志记录。
- 在 Lambda 可运行输出日志的函数代码之前,已达到函数的持续时间限制。
如果您在查看日志之后无法确定导致超时的原因,请尝试以下一种或多种解决方法:
- 验证您使用的 AWS SDK 上的重试计数和超时设置是否有充足的时间让函数初始化。
- 临时提高 Lambda 函数的超时设置,以便有充足的时间让函数代码生成日志数据。
- 提高函数的配置内存,帮助减少调用持续时间延迟并提高计算能力。
要将更多日志记录输出添加到函数的代码,请参阅以下有关您正在使用的 Lambda 运行时的文档:
- 采用 Node.js 编写的 AWS Lambda 函数日志记录
- 采用 Python 编写的 AWS Lambda 函数日志记录
- 采用 Ruby 编写的 AWS Lambda 函数日志记录
- 采用 Java 编写的 AWS Lambda 函数日志记录
- 采用 Go 编写的 AWS Lambda 函数日志记录
- 采用 C# 编写的 AWS Lambda 函数日志记录
- 采用 PowerShell 编写的 AWS Lambda 函数日志记录
使用 AWS X-Ray 确定任何代码的性能瓶颈
如果您的 Lambda 函数调用下游 AWS 资源、微服务、数据库或 HTTP Web API,请使用 AWS X-Ray 来排查代码性能问题。
有关更多信息,请参阅将 AWS Lambda 与 AWS X-Ray 结合使用。
使用 Lambda Insights 收集函数的系统级指标
Lambda Insights 收集系统级指标,包括 CPU 时间、内存、磁盘和网络指标。此外,它还会收集诊断信息,包括冷启动次数和 Lambda 工作线程关闭次数,以帮助您隔离与 Lambda 函数相关的问题。
有关更多信息,请参阅使用 Lambda Insights。
**注意:**使用 Lambda Insights 会在 AWS 账户中产生费用。您需要为 Lambda 扩展所使用的调用时间付费,以 1 毫秒为增量。
使用 VPC 流日志确定特定调用请求被拒或未路由的原因
VPC 流日志使您能够查看流入和流出 Amazon Virtual Private Cloud(Amazon VPC)的所有网络流量。
有关更多信息,请参阅排查 Lambda 中的联网问题。
**注意:**请记住,如果选择设置 VPC 流日志:
- 当您将流日志发布到以下任一对象时,将收取对公开日志的数据提取和存档费用。
- CloudWatch Logs
- Amazon Simple Storage Service (Amazon S3)
- 当您将 Lambda 函数配置为访问 Amazon VPC 中的资源时,Lambda 会将该函数分配给弹性网络接口。要识别与 Lambda 函数关联的网络流量,您必须找到函数的网络接口。有关说明,请参阅为什么我不能分离或删除 Lambda 创建的弹性网络接口?
使用 HTTP 线路跟踪对函数代码在调用过程中生成的网络请求进行详细的日志记录
有关更多信息,请参阅对 HTTP 线路跟踪进行日志记录。
防止 Lambda 函数超时的最佳实践
确保 Lambda 函数保持幂等性
由于临时网络问题,API 调用所花费的时间可能比预期的要长。网络问题还可能会造成重试和重复的 API 请求。要为这些情况做好准备,请确保您的 Lambda 函数保持幂等性。
有关更多信息,请参阅如何让我的 Lambda 函数保持幂等性?
在函数处理程序之外初始化函数的静态逻辑
初始化 Lambda 函数时,Lambda 最多会分配 10 秒来完成调用的初始化阶段。由于此时间限制,最好是在初始化代码中的函数处理程序外执行以下操作:
- 导入库和依赖项
- 设置初始配置
- 初始化至其他下游服务和资源的连接
这种静态初始化允许这些资源在每个沙盒中初始化一次,然后在同一个运行时环境中将来的所有调用中重复使用。
有关更多信息,请参阅优化静态初始化。此外,《Lambda 操作指南》中的下游不可用性和《Lambda 开发人员指南》中的函数代码。
**注意:**Lambda 将会删除至下游资源的空闲连接。要允许函数维持持久连接,请使用与您正在使用的 Lambda 运行时关联的 tcp_keepalive 变量。
验证您使用的 AWS SDK 上的重试计数和超时设置是否有充足的时间让函数初始化
如果您使用 AWS SDK 进行 API 调用且调用失败,则该 AWS SDK 会自动重试调用。AWS SDK 重试的次数以及时间由每个 AWS SDK 之间不同的的设置决定。初始化函数所需的时间可能超过默认 AWS SDK 设置允许的时间。
有关更多信息,请参阅如何对使用 AWS SDK 调用 Lambda 函数时出现的重试和超时问题进行故障排查?
(可选)为 Lambda 函数配置预置并发
预置并发初始化请求数量的运行时环境,以便它们准备好立即响应函数的调用。要为函数设置预置并发,请按照配置预置并发中的说明进行操作。
**注意:**配置预置并发会向您的 AWS 账户收取费用。您可以在函数的某个版本或 Lambda 函数别名上配置预置并发。
验证 Lambda 函数是否有足够的系统资源
向 Lambda 函数调用分配的网络带宽和 CPU 量由函数的内存配置决定。
有关更多信息,请参阅《Lambda 操作指南》中的内存和计算能力。
确保 Lambda 函数使用的任何后端进程在函数处理程序返回字符串之前均已完成
有关更多信息,请参阅了解 AWS Lambda 中的容器重用。
验证 Lambda 函数是否已配置为在任何集成 AWS 服务的最大超时设置内工作
即便 Lambda 函数的最大调用超时限制为 15 分钟,其他 AWS 服务也可能具有不同的超时限制。
例如,Amazon API Gateway 最多会等待 29 秒来完成 Lambda 函数代理调用。有关更多信息,请参阅如何解决在将 API Gateway 与 Lambda 函数集成时收到的错误? 另外,请参阅将 AWS Lambda 与其他服务结合使用。
确认您的函数正在尝试访问的端点具有有效的网络路径
要查看您的网络设置,请按照如何排查 Amazon VPC 中 Lambda 函数的超时问题?中的说明进行操作。
相关内容
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前
- AWS 官方已更新 2 年前