更新记录
1.0.1(2026-11-11)
1.0.1
- 重新打包上传,使云函数被平台正确识别并加密
- 代码与 1.0.0 一致,无功能改动
1.0.0(2026-11-11)
首个版本。
- 十个 action:register / begin / heartbeat / finish / retry / runs / detail / stats / clean
- 任务配置与执行记录共用一个集合,只需上传一个 Schema
- 同名防重,超时未心跳自动标记 timeout 并允许接管
- 长任务心跳续期,重复 finish 不覆盖首次结果
- 失败可按 attempt 重试,同一条失败只重试一次
- 成功率、平均耗时、失败排行统计,附管理页
平台兼容性
云端兼容性
| 支付宝云 | 腾讯云 | 阿里云 |
|---|---|---|
| × | √ | √ |
uniCloud 定时任务调度与执行留痕
零第三方依赖的 uniCloud 云端一体工具:任务注册、同名防重、执行开始与结束留痕、失败重试、超时接管、成功率与耗时统计,附一个开箱即用的管理页。
uniCloud 的定时触发负责「什么时候跑」,本插件负责「谁在跑、跑了多久、成功没有、失败了要不要重试」。适合有多个定时任务、需要知道昨晚那次结算到底跑没跑、以及怕重复执行的场景。
特性
- 任务注册:每个任务可配超时时间、最大重试次数、是否允许并发
- 同名防重:
begin时若已有未超时的 running 执行则拒绝;超时未心跳的自动标记timeout并允许接管 - 完整留痕:开始 / 心跳 / 结束时间、耗时、尝试次数、状态、错误摘要、结果摘要
- 失败重试:
finish返回是否可重试,retry基于失败执行创建下一次尝试 - 统计:成功率、平均耗时、运行中数量、失败排行
- 不存业务正文:
result是摘要并有大小上限,error截断,插件不执行业务代码 - 零依赖:只用
uniCloud.database(),不引 npm 包或扩展库 - 自带管理页:注册、开始、标记成功/失败、重试、统计、执行记录、清理过期
目录结构
uni_modules/aliang-schedule/
├── package.json 插件配置(含定价与加密清单,只列 1 个 js)
├── pages_init.json 自动注册管理页
├── readme.md / changelog.md
├── uniCloud/
│ ├── cloudfunctions/aliang-schedule/index.js 单文件云函数
│ └── database/
│ ├── cloud_schedule_runs.schema.json
│ └── cloud_schedule_runs.index.json 三个索引
└── pages/schedule/list.vue 管理页
任务配置与执行记录共用一个集合,用 kind 区分 task / run。单文件云函数的理由同系列产品:加密清单按文件配置,多文件漏配会明文外泄。
五分钟接入
第 0 步:在 uniCloud 服务空间配置环境变量:
SCHEDULE_TOKEN = 一个足够长的随机字符串
未配置时除 ping 外所有 action 拒绝,这是默认安全。
- 导入插件到 uni-app 项目。
- 上传
uniCloud/database/cloud_schedule_runs.schema.json。 - 右键
uniCloud/cloudfunctions/aliang-schedule→ 上传部署。 pages_init.json会自动提示注册「任务调度」页。- 在你的定时触发云函数里调用本插件(示例见下),管理平台只用来看结果。
试用 5 分钟自检(7 天试用内照做即可判定插件是否合用)
| 步骤 | 操作 | 预期结果 |
|---|---|---|
| 1 | action: 'ping' |
configured: true,返回默认超时与重试次数 |
| 2 | 管理页填任务名,点「注册任务」 | 提示已注册,显示超时与最大重试 |
| 3 | 点「开始一次执行」 | 返回 runId,状态 running |
| 4 | 不标记完成,再点一次「开始一次执行」 | 返回 acquired: false / already-running(同名防重生效) |
| 5 | 点「标记失败」 | 提示可重试,执行记录状态 failed |
| 6 | 点「重试」 | 生成新的 runId,attempt 加 1 |
| 7 | 统计卡片 | 成功率、运行中、失败数、平均耗时随操作变化 |
任一步不符,先看页面错误提示,再检查 SCHEDULE_TOKEN 与 Schema 是否上传。
环境变量
| 变量 | 默认 | 说明 |
|---|---|---|
SCHEDULE_TOKEN |
空(必填) | 所有 action 的令牌,只从环境变量读 |
SCHEDULE_COLLECTION |
cloud_schedule_runs |
记录集合名,只从环境变量读 |
SCHEDULE_DEFAULT_TIMEOUT_MS |
300000 | 默认执行超时(5 分钟) |
SCHEDULE_DEFAULT_MAX_RETRIES |
3 | 默认最大重试次数 |
SCHEDULE_MAX_RESULT |
4000 | 结果摘要序列化上限,超限只记长度标记 |
SCHEDULE_RETENTION_DAYS |
14 | 执行记录保留天数 |
超时、重试、结果上限、保留天数可用 data.config 覆盖;令牌与集合名不接受请求侧覆盖。
API 参考
云函数名 aliang-schedule,统一返回 { errCode: 0 | 字符串, errMsg, data },失败错误码以 aliang-schedule- 开头。
| action | 说明 | 主要参数 | 需要 token |
|---|---|---|---|
ping |
健康检查 | — | 否 |
register |
注册 / 更新任务配置 | name timeoutMs maxRetries allowConcurrent |
是 |
begin |
开始一次执行 | name owner attempt |
是 |
heartbeat |
长任务心跳续期 | runId |
是 |
finish |
结束执行 | runId status(success/failed) result error |
是 |
retry |
基于失败执行创建下一次尝试 | runId owner |
是 |
runs |
执行记录列表 | task status page pageSize |
是 |
detail |
执行详情 + 任务配置 | runId |
是 |
stats |
成功率、平均耗时、失败排行 | — | 是 |
clean |
清理过期的已结束记录 | — | 是 |
状态:running / success / failed / timeout / abandoned。
在定时触发云函数里接入
const sched = (action, extra) => uniCloud.callFunction({
name: 'aliang-schedule',
data: Object.assign({ action, token: SCHEDULE_TOKEN }, extra)
}).then(r => r.result)
exports.main = async () => {
const b = await sched('begin', { name: 'daily-settlement', owner: 'cron-settlement' })
if (!b.data.acquired) return { errCode: 'skipped', errMsg: b.data.reason }
const timer = setInterval(() => {
sched('heartbeat', { runId: b.data.runId }).catch(() => {})
}, 60000)
try {
const result = await doSettlement()
clearInterval(timer)
await sched('finish', { runId: b.data.runId, status: 'success', result: { count: result.count } })
return { errCode: 0 }
} catch (e) {
clearInterval(timer)
const f = await sched('finish', { runId: b.data.runId, status: 'failed', error: e.message })
if (f.data.retryable) {
// 可交给下一次触发,或立即调 retry 创建下一次尝试
}
throw e
}
}
定时触发的参数由 uniCloud 控制台配置,令牌不要写进前端代码。
heartbeat用于长任务续期,短任务可以省掉。
安全与限制
- 令牌与集合名只从环境变量读;任务名做了控制字符与长度约束。
- 记录集合
permission全为false,前端无法直连。 - 结果摘要有大小上限,超限只保留长度标记;
error截断到 1000 字符;不存业务正文。 clean只删除已结束且过期的run记录,不会删除任务配置,也不会删除running状态的执行。- 同名防重是尽力而为:
begin先查再写,两个触发极端并发时仍可能同时通过。业务侧仍应自己保证幂等,或配合分布式锁插件。 - 超时判断基于
heartbeat_at/started_at,长任务不心跳会被判定超时并允许被接管。 stats的平均耗时基于最近 200 条记录,不是全量统计。- 第一版不提供 cron 表达式解析、任务编排与依赖链;调度时机由 uniCloud 定时触发负责。
常见问题
Q:报 token-required / unauthorized。 没配 SCHEDULE_TOKEN 或传的不一致,用 ping 确认。
Q:begin 返回 already-running。 同名任务已有执行中且未超时;确认上一次是否卡住,或调大 timeoutMs,或等待超时后自动接管。
Q:重复 finish 会怎样。 返回 updated: false 与当前状态,不会覆盖首次结果。
Q:retry 报 retry-exhausted。 已达任务的最大重试次数,可在 register 里调大 maxRetries。
Q:统计里成功率一直是 0。 需要有 success 或 failed 的已结束记录;只有 running 不计入。
Q:报 collection-missing。 Schema 没上传。
版本要求与授权
HBuilderX 4.71+,uniCloud 阿里云 / 腾讯云;JavaScript 普通云函数(CommonJS),零扩展库。付费普通授权版按服务空间 spaceId 绑定,提供 7 天试用。
授权按 DCloud 插件市场的标准条款,可用于自己的任意商业项目,项目数量不限;禁止把插件本身(含换皮版本)作为插件 / 源码 / 模板再次分发或转售。
运行时行为要点
- 一次失败只会被重试一次:
retry先用条件更新抢占父执行的retried标记。同一条失败执行重复调用会返回alreadyRetried: true并带上已创建那条的runId,不会重复起新执行。想再试一次,请对最新那条失败的执行调用retry。 - 同名防重是尽力而为:
begin的「先查后写」不是原子操作,极端并发下两个触发都可能通过。业务侧仍需保证幂等,或配合分布式锁插件。allowConcurrent: true时本来就不做防重。 - 超时接管带条件:只在
heartbeat_at没变时才把执行标记为timeout,刚续期的执行不会被误杀。 stats是近似值:平均耗时与失败排行基于最近 200 条已结束记录,不是全量聚合。- 令牌会出现在云函数日志里:
callFunction的参数在日志中可见,这是 uniCloud 的既有行为。定时触发函数请从环境变量读令牌,不要硬编码;怀疑泄露时改环境变量即可。

收藏人数:
购买源码授权版(
导入插件并试用
赞赏(0)
下载 0
赞赏 1
下载 35291
赞赏 159
赞赏
京公网安备:11010802035340号