作者:渐意
前言任务系统中有一类很重要的概念,即任务的状态。其本质是对任务的生命周期管理。细分的状态有助于在使用时能够更清楚的了解系统发生了什么内容,便于针对性的根据业务情况进行操作。函数计算ServerlessTask提供了多种可查询的状态,并提供了各状态间转移的时间点。在函数的执行层面,函数计算也提供了任务的生命周期管理概念,用户可以根据需求决定当系统对任务实例进行初始化、回收等一系列动作时的执行逻辑,实现完整的运行时生命周期管理。本文将分别对任务运行状态及运行时管理这两个方面的内容进行介绍。
任务的状态及生命周期的管理任务的状态管理当用户提交任务并收到提交成功的返回后,任务便已经进入系统对其生命周期的管理流程中。一个任务的状态变更由内部的一个状态机负责管理,并对外透出状态支持实时查询。整个状态转换图如下所示:
图1
用户触发一次任务后,任务入队,变更为Enqueued状态,并返回触发成功;任务在函数计算后端服务中出队,任务变为Dequeued状态;后端会检查任务配置。如果配置了异步消息有效期功能,并且该消息出队时间与入队时间之差已超过有效期,则任务被丢弃,变更为Expid状态。任务终止;任务对应的函数已被删除,或创建实例出现错误,则丢弃消息,任务变更为Invalid状态;检查后任务正式进入Running状态。此时任务已触发实际的执行;任务执行完成后,根据返回会变更为以下几个状态:Retrying:用户配置了重试次数(默认为3),且任务执行失败,这时会进入重试中状态,之后会变更为Running状态;Failed:任务执行失败,且超过了重试次数。此时会将任务状态改为Failed;Succeeded:任务执行成功。如果在整个状态流转过程用户触发Cancel,则任务会先变更为Stopping状态,并尝试停止任务执行。当任务停止执行成功后,任务进入Stopped状态。任务运行时管理及生命周期当任务状态进入Running后,任务的实际执行便已交给函数计算的运行时。在安全性方面,函数计算会按照VM对不同账号进行隔离,同一个账号下的函数可能运行于同一个VM中。VM内有一个负责管理容器的客户端,来实际触发函数的执行,并收集执行结果。
用户的运行实例有几个不同的状态:
图2
函数计算对上述所有实例状态变化的过程均提供接口,支持用户侧配置相应的逻辑。
创建完成-执行请求阶段:支持Initializer功能,支持初始化实例操作。用户可以配置诸如全局变量、连接池初始化等相关操作;执行中-执行完成后Pause实例:支持PFeze接口,支持在函数Pause实例前执行用户侧的自定义逻辑;执行中-外部cancel:函数计算会强制Restart用户实例,在Restart前支持PStop接口。用户可以配置优雅停止的相关逻辑,以便支持Cancel时的自定义行为;完成后Pause-销毁实例:当一段时间没有请求后,函数计算将销毁实例。此时会调用PStop接口,用户可以配置销毁容器的行为(如关闭连接池等)。图3
任务的停止操作目前阶段函数计算支持了停止单一任务的操作。当用户操作停止时,支持配置PStop接口,在停止前进行一系列的资源回收工作。停止操作用户可以使用SDK或控制台来进行调用。以Go语言为例,停止一次执行的伪代码如下所示:
importfc"github.