# 异步任务场景使用指南

[服务常识](/minigame/dev/wxcloudrun/src/guide/debug/know)中有一条描述：

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

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

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

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

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

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

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

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

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

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

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

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

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

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

## 真实例子

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

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

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

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

![](https://res8.wxqcloud.qq.com.cn/wxdoc/884487e1-12e8-4ea2-a496-e133f09f1959.png)

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