Lambda在一个执行环境中调用你的函数,其提供了一个安全和隔离的运行环境。执行环境管理着运行你的函数所需的资源。执行环境还为函数的运行时间和任何与你的函数相关的外部扩展提供生命周期的支持。
函数的运行时使用Runtime API与Lambda进行通信。Extensions使用Extensions API与Lambda进行通信。Extensions也可以通过使用Logs API订阅日志来接收来自该函数的日志信息。
当你创建Lambda函数时,你会指定配置信息,如可用的内存量和允许函数的最大执行时间。Lambda使用这些信息来设置执行环境。
函数的运行时间和每个外部扩展本质是在执行环境中运行的进程。权限、资源、凭证和环境变量在函数和扩展之间共享。
Lambda执行环境的生命周期
执行环境的生命周期包括以下阶段:
Init:在这个阶段,Lambda用配置好的资源创建或解冻一个执行环境,下载函数和所有层的代码,初始化任何扩展,初始化运行时,然后运行函数的初始化代码(主处理程序之外的代码)。如果你已经启用了配置并发,Init阶段要么发生在第一次调用期间,要么在函数调用之前发生。
Init阶段被分成三个子阶段。扩展启动,运行时启动,和函数启动。这些子阶段确保所有扩展和运行时在函数代码运行前完成它们的设置任务。
Invoke:在这个阶段,Lambda会调用函数处理程序。在函数运行完成后,Lambda准备处理另一个函数的调用。
Shutdown:如果Lambda函数在一段时间内没有收到任何调用,就会触发这个阶段。在Shutdown阶段,Lambda会关闭运行时,提醒扩展,让它们干净地停止,然后删除环境。Lambda会向每个扩展发送一个Shutdown事件,告诉扩展环境即将被关闭。
每个阶段都以Lambda向运行时和所有注册的扩展发送一个事件开始。运行时和每个扩展通过发送一个Next API请求来表示完成。当运行时和每个扩展完成后,Lambda就会冻结执行环境,并且没有待处理的事件。
Init阶段
在初始阶段,Lambda执行三项任务:
启动所有扩展(Extension init)
引导运行时(Runtime init)
运行函数的静态代码(Function init)
当运行时和所有扩展通过发送Next API请求发出准备好的信号时,Init阶段结束。Init阶段的时间限制为10秒。如果这三个任务都没有在10秒内完成,Lambda会在第一个函数调用时重试Init阶段。
Invoke阶段
当Lambda函数被调用以响应Next API请求时,Lambda会向运行时和每个扩展发送一个Invoke事件。
该函数的超时设置限制了整个Invoke阶段的持续时间。例如,如果你把函数的超时设置为360秒,那么函数和所有扩展都需要在360秒内完成。注意,不存在独立的后调用阶段。持续时间是所有调用时间的总和(运行时间+扩展),在函数和所有扩展执行完毕后才会计算。
调用阶段在运行时和所有扩展通过发送Next API请求表示完成后结束。
如果Lambda函数在调用阶段崩溃或超时,Lambda将重置执行环境。重置的行为类似于关机事件。首先,Lambda关闭了运行时。然后Lambda向每个注册的外部扩展发送一个Shutdown事件。该事件包括关闭的原因。如果另一个Invoke事件导致这个执行环境被重用,Lambda会初始化运行时和扩展,作为下一次调用的一部分。
Shutdown阶段
当Lambda即将关闭运行时时,它会向运行时和每个外部扩展发送一个Shutdown事件。扩展可以利用这段时间进行最后的清理任务。Shutdown事件是对Next API请求的一个响应。
持续时间。整个关闭阶段的时间上限为2秒。如果运行时或任何扩展没有响应,Lambda会通过一个信号(SIGKILL)将其终止。
在函数和所有扩展完成后,Lambda会维持执行环境一段时间,以期待另一个函数的调用。实际上,Lambda冻结了执行环境。当函数被再次调用时,Lambda会解冻环境,以便重新使用。重用执行环境有以下影响。
在函数处理方法之外声明的对象仍然被初始化,当函数被再次调用时提供额外的优化。例如,如果你的Lambda函数建立了一个数据库连接,而不是重新建立连接,在随后的调用中会使用原来的连接。我们建议在你的代码中加入逻辑,在创建一个新的连接之前检查连接是否存在。
每个执行环境在/tmp目录下提供512MB的磁盘空间。当执行环境被冻结时,该目录的内容仍然存在,提供了一个瞬时的缓存,可以用于多次调用。你可以添加额外的代码来检查缓存中是否有你存储的数据。关于部署大小限制的更多信息,请参阅Lambda配额。
如果Lambda重用执行环境,由你的Lambda函数启动的、在函数结束时没有完成的后台进程或回调会恢复。请确保你的代码中的任何后台进程或回调在代码退出前已经完成。
当你编写你的函数代码时,不要假设Lambda会自动为后续的函数调用重用执行环境。其他因素可能决定了Lambda需要创建一个新的执行环境,这可能导致意想不到的结果,如数据库连接失败。