

延时任务是为了实现在特定时刻点执行指定操作的任务类型，虽然这个需求通过系统中Quartz的一次性调度实现，但是这种方式实现起来比较重，为此系统使用时间轮算法实现了轻量级的延时任务，并且支持多节点和持久化保障可用性，非常适合任务数量特别大的场景。

使用延时任务的典型场景例如：在电商业务中下单后10分钟没有支付则发送提醒短信，30分钟没有支付则超时自动取消，还比如未抢完的红包自动退款等等。

延时任务的实现有很多种，常见的方案包括：Quartz定时任务、数据库轮询、集合轮询、Redis有序集合、消息队列、时间轮算法等等，本项目采用了时间轮算法（也称为环形队列）作为实现原理，关于这个原理作者曾经写过一篇文章[https://www.cnblogs.com/hohoa/p/7739271.html] 来做介绍，项目中即是在这个基础上改进而来。

<br />

### 概况

![ ](https://imgkr.cn-bj.ufileos.com/b81930d6-e067-4086-ad1d-df69d9ff1623.png)

- **重置**：非已就绪的任务重新加入执行计划中。

- **执行**：执行异常的任务立即执行一次回调。

- **作废**：把已创建或已就绪的任务移除。

- **日志**：查看任务运行轨迹和日志。

<br />

### 创建任务

项目提供了2种创建方式：控制台和WebAPI，但是在实际情况中使用API创建的方式明显更符合要求，这里只介绍下控制台如何创建以及注意事项，API创建请参考【[使用API接入任务](https://github.com/hey-hoho/ScheduleMasterCore/blob/master/docs/2-%E4%BD%BF%E7%94%A8API%E6%8E%A5%E5%85%A5%E4%BB%BB%E5%8A%A1.md)】。

控制台创建任务页面：

![ ](https://imgkr.cn-bj.ufileos.com/80abe245-e70b-42bf-bce9-a8ec1ff94429.png)

- **来源**：用来标记任务来自哪个业务系统。

- **主题**：用来标记任务属于哪一个子业务，以上2个字段方便对任务做分类查询。

- **业务关键字**：用来标记业务实体的唯一码，例如用户编码、订单编码、门店编码等。

- **延迟相对时间**：任务就绪时相对当前服务器时间的间隔，单位是秒，必须是正整数否则就绪失败。

- **延迟绝对时间**：任务执行的绝对时间，以上两种模式选其一，默认是相对模式，可以在系统参数中配置。

- **回调地址**：要执行业务的入口，**由于可能存在多次回调，请务必做好幂等性处理**，多次回调的情况包括重置任务、异常重试、手动执行、多个节点存在系统时间差等等。

- **数据格式**：回调接口接收的参数格式，仅支持json和form两种。

- **回调参数**：要传递给回调接口的数据，对应数据格式的json字符串。

- **执行节点**：执行任务所在的节点。

任务创建成功后立即进入已就绪状态，意味着已加入到执行计划中等待执行。

<br />

### 失败重试

系统支持执行失败后进行重试功能，重试间隔以及重试次数可以在系统参数中配置：

![ ](https://imgkr.cn-bj.ufileos.com/25b32501-71ce-47a0-81cf-0bc145ffcb4c.png)

重试效果：

![ ](https://imgkr.cn-bj.ufileos.com/78738b1c-60c0-407a-9b62-157f641edf29.png)

达到最大重试次数后任务会进入到异常状态，并给创建者发送告警邮件通知，这时候可以选择人工介入处理。