View a markdown version of this page

了解 Lambda 托管实例执行环境 - Amazon Lambda
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

了解 Lambda 托管实例执行环境

Lambda 托管实例提供了一种备选部署模式,即在客户自有的 Amazon EC2 实例上运行您的函数代码,而 Lambda 则负责管理相关运营事务。托管实例的执行环境与 Lambda(默认)函数存在多个重要差异,尤其是在处理并发调用和管理容器生命周期方面。

注意:有关 Lambda(默认)执行环境的信息,请参阅了解 Lambda 执行环境生命周期。

执行环境生命周期

Lambda 托管实例函数执行环境的生命周期与 Lambda(默认)在几个关键方面有所不同:

Init 阶段

在初始化阶段,Lambda 会执行以下步骤:

  • 初始化并注册所有扩展程序

  • 引导运行时入口点。运行时会启动所配置数量的运行时工作进程(实施取决于运行时)

  • 运行函数初始化代码(处理程序之外的代码)

  • 等待至少一个运行时工作进程通过调用 /runtime/invocation/next 发出准备就绪信号

当扩展程序已初始化并且至少有一个运行时工作进程已调用 /runtime/invocation/next 时,初始化阶段即被视为已完成。然后,该函数即准备好处理调用。

注意

对于 Lambda 托管实例函数,初始化最长需要 15 分钟。超时时间为最大值 130 秒,或者为配置的函数超时时间(最长可达 900 秒)。

调用阶段

Lambda 托管实例函数的调用阶段具有几个独特的特征:

持续运行。与 Lambda(默认)不同的是,其执行环境始终处于持续运行状态,能够实时处理接收到的调用,而不会在每次调用之间出现停滞。

并行处理。在同一个执行环境中,可以同时进行多次调用,每项调用都会由不同的运行时工作进程来处理。

独立超时。该函数的配置超时适用于每次单独的调用。当一次调用超时后,Lambda 会将该特定调用标记为失败,但不会中断其他正在运行的调用或终止执行环境。

背压处理。如果所有运行时工作进程都在忙于处理调用,那么新的调用请求将会被拒绝,直到有工作进程可用为止。

错误处理和恢复

Lambda 托管实例函数执行环境中的错误处理与 Lambda(默认)不同:

运行时工作进程故障。如果某个运行时工作进程崩溃,执行环境会继续依靠其余正常运行的工作进程来维持运行。

扩展程序崩溃。如果扩展进程在初始化或操作期间崩溃,则整个执行环境将被标记为不正常并被终止。Lambda 会创建一个新的执行环境来替换它。

无法重置/修复。与 Lambda(默认)不同的是,托管实例不会在出错后尝试重置和重新初始化执行环境。相反,运行状况不佳的容器会被终止并由新的容器替代。

调用超时

当单个调用超时时,Lambda 会向调用方返回一个状态为函数错误的Task timed out after <timeout> seconds 的错误。但是,Lambda 托管实例不会强制终止您的代码——它会继续在执行环境中运行。作为函数开发人员,您负责检测和处理超时。上下文对象会暴露调用的剩余时间。零或负值表示调用已超时。执行环境中的其他并发调用继续正常处理。

重试行为

当调用超时时:

  • 同步调用:调用方收到超时错误并负责重试。

  • 异步调用:Lambda 根据函数的重试策略进行重试(默认:2 次重试)。所有重试用尽后,事件将被发送到配置的死信队列或失败目标(如果有)。

  • 事件源映射:重试行为取决于事件源配置(例如,批次大小、出错时是否二分、最大重试次数)。根据您的重试策略,批次可能会被重试或发送到失败目标。

如果不处理超时会发生什么

如果您的代码不检查剩余时间并停止执行:

  • 调用已被标记为失败。Lambda 已向调用方返回超时错误——您的代码在超时之后完成的任何工作实际上都已丢失(从调用方角度来看)。

  • 资源仍被占用。您的代码会继续占用运行时工作线程槽位,从而减少该实例上可用于新调用的并发数。

  • 非确定性行为。您的代码在超时触发时并不会停止——它会在后台继续运行。这意味着在 Lambda 已告知调用方调用失败之后,副作用仍可能发生。例如,您的处理程序向 DynamoDB 写入一条记录,然后超时触发,Lambda 向调用方返回超时错误,但您的代码仍在运行并继续发送 SNS 通知。调用方重试调用,这会再次写入记录并再次发送通知。您现在拥有重复数据和重复通知——并且无法轻松区分哪些来自仍在后台运行的“失败”调用。

在代码中处理超时

使用上下文对象检查剩余时间并在超时之前停止处理。根据下一工作单元的预期持续时间配置缓冲时间——例如,如果每个项目处理大约需要 500 毫秒,则将缓冲时间设置为至少 500 毫秒并留有余量。

有关超时处理的语言特定示例,请参阅每个运行时页面的请求上下文部分: