# 异步任务场景使用指南

服务常识中有一条描述:

代码中请不要在请求处理程序范围之外启动后台线程或例程,并确保在传送响应之前完成所有异步操作。

有很多开发者不太理解为什么这么建议,如果有异步任务的情况下,应该如何使用才正确呢?本文就来给大家详细解读一下

# 请不要在请求处理程序范围之外启动后台线程或例程

这是一条建议,比如说,你的一个 HTTP 服务,在收到一个接口后,直接调用 sh 命令,做系统层面的动作。如系统文件更新,指向,重启等,这都是不建议的,会引发不稳定导致回收。

请不要将云托管服务的实例当成自己的开发调试机器,进行无规程运算,挖矿,阵列控制等不是以应用服务为目的的操作。如果有相关的需要请直接去云厂商购买 CVM 服务器。

云托管服务目的是提供「小程序/公众号H5/WEB/APP」等应用的资源分发和后端服务,整个形态是经过特殊包装的,不要将其理解成 CVM 服务器,虽然你可以进行绝大部分的系统操作,但是你无法控制实例服务的重启,新增,销毁,这些权限都是由云托管集群自己控制的。

# 确保在传送响应之前完成所有异步操作

我们举一个例子帮助理解。

当你的服务最小实例为0(低成本模式),你触发执行一个异步任务,时间达2小时。

这个时间段中如果没有任何访问请求的话,半小时就直接缩容到0了,所以要保证实例不会回收,你需要半小时内触发更新的实例的时间,一直到你的异步任务执行完毕。

当你设置的最小实例等于1(高可用模式),当前确实只有1个实例正在运行,而你的异步任务刚好在这唯一的容器里执行,你无需半小时触发,他一直存在。

但是当你的业务出现高峰,有2个甚至更多实例存在,这时候如果有异步任务2小时,但你2小时内的流量访问不足以支撑2个或多个容器提供服务,那就会缩容到1(你设置的最小实例),你的异步任务如果刚好在缩容的那个容器中,就会夭折。

因为云托管的服务是根据你的流量请求以及你的设置,持续扩缩容,弹性的变化实例数量提供服务。所以这种情况下,你必须约束任务,或者是通过守护请求来支撑住,这个过程需要你自己根据业务需要操作,总体而言需要有比较强的基础和理解能力才能保证顺利。

这也是为什么我们建议尽量在请求响应前完成异步操作的原因。当然你也可以理解上述扩缩容逻辑,来设定异步执行。

# 真实例子

以下是一个真实的例子,场景是:每天凌晨开始数据迁移任务,时长大概在3小时。

使用的云函数定时触发器,在凌晨前先将迁移服务拉起来(冷启动1分钟),然后执行异步任务。

在这个过程中,防止容器缩容,每15分钟发起请求,保持活跃。

最终到5点半结束请求,迁移服务半小时后自动缩容。

这里需要注意的是,你的服务规格配置需要满足异步任务的运行要求,不要因为内存/CPU达到扩容条件而产生多个实例。设置内存/CPU条件大于95%,降低因为突刺导致的扩容概率。