主题
定时任务 PRD
文档信息
| 项目 | 内容 |
|---|---|
| 产品名称 | PMForge - 定时任务 |
| 文档版本 | v2.0 |
| 创建日期 | 2026-09-17 |
| 最后更新 | 2026-09-24 |
| 文档状态 | 评审中 |
| 优先级 | P0 |
一、功能概述
1.1 功能定位
定时任务是 PMForge 平台的"自动闹钟系统"——你告诉它"每天凌晨 2 点清理过期订单""每 5 分钟同步一次支付状态""每月 1 号统计上月数据",它就会准时自动执行,不需要人工干预。
它基于业界成熟的 Quartz 调度引擎构建,提供了可视化的管理界面:不用写代码、不用登录服务器改配置文件,在网页上就能创建、编辑、暂停、手动触发定时任务,并查看每一次执行的详细日志。
1.2 目标用户
| 用户类型 | 核心诉求 | 典型操作 |
|---|---|---|
| 系统管理员 | 管理所有定时任务,确保自动化流程正常运转 | 创建任务 → 配置 Cron → 启用 → 查看日志 |
| 运维人员 | 排查任务异常,处理告警 | 收到失败告警 → 查看日志 → 定位异常原因 |
| 后台开发者 | 注册新的任务处理器,调试任务逻辑 | 写 JobHandler Bean → 创建任务 → 立即执行 → 确认结果 |
| 产品经理 | 了解系统自动化运行情况 | 查看执行统计面板 → 关注关键任务成功率 |
1.3 业务价值
- 减少人工操作:把重复性的后台工作(数据清理、状态同步、统计汇总)交给系统自动完成,运维人员不用每天手动跑脚本
- 可视化管理:所有任务一目了然——哪些在跑、哪些暂停了、上次执行结果如何,不用登录服务器查日志
- 失败自动重试:任务执行失败后自动按配置重试,减少"偶发网络抖动导致任务失败"的人工介入
- 完整的执行日志:每次执行都有详细记录(开始时间、结束时间、耗时、执行结果、异常信息),出问题时有据可查
- 服务重启自动恢复:任务配置持久化到数据库,服务器重启后自动恢复调度,不丢任务
1.4 功能范围
| 功能分类 | 后台管理端 | 说明 | 优先级 |
|---|---|---|---|
| 任务管理(增删改查) | ✅ | 创建、编辑、删除定时任务 | P0 |
| 任务状态管理 | ✅ | 暂停/恢复任务调度 | P0 |
| 手动触发执行 | ✅ | 立即执行一次任务 | P0 |
| 任务日志查看 | ✅ | 查看每次执行的详细日志 | P0 |
| Cron 表达式预览 | ✅ | 预览未来 N 次执行时间 | P1 |
| 任务同步 | ✅ | 修复数据库与调度引擎数据不一致 | P1 |
| 任务/日志导出 | ✅ | 导出 Excel | P1 |
| 异常告警 | ✅ | 任务失败/超时时发送通知 | P1 |
| 执行统计面板 | ✅ | 执行次数、成功率、趋势图 | P2 |
| 批量操作 | ✅ | 批量暂停/恢复/删除 | P2 |
二、用户场景
2.1 用户角色
| 角色 | 描述 | 核心诉求 |
|---|---|---|
| 系统管理员老周 | 负责系统全局配置 | 任务创建后自动运行,不需要反复操心 |
| 运维工程师小吴 | 负责系统监控和故障排查 | 任务出问题时第一时间知道,快速定位原因 |
| 后端开发小韩 | 负责业务模块开发 | 写好处理器后能快速注册任务并验证效果 |
| 产品经理小陈 | 关注系统运行健康度 | 一眼看出哪些任务不稳定、成功率如何 |
2.2 使用场景
场景1:管理员创建"每日订单清理"任务
- 用户:系统管理员老周
- 场景:业务要求每天凌晨 2 点自动清理 30 天前的过期订单
- 操作步骤:
- 进入"基础设施 → 定时任务"页面
- 点击"新增"按钮 → 弹出任务配置表单
- 填写任务名称:"过期订单自动清理"
- 处理器名称输入:
tradeOrderCleanJob(开发者已注册好的 Bean) - 处理器参数输入:
30(表示清理 30 天前的数据) - Cron 表达式输入:
0 0 2 * * ? - 点击 Cron 旁边的"预览"按钮 → 看到未来 5 次执行时间都是凌晨 2 点 → 确认正确
- 重试次数设为 3,重试间隔设为 5000 毫秒(5 秒)
- 监控超时时间设为 300000 毫秒(5 分钟)
- 点击"保存" → 系统提示"创建成功"
- 任务自动进入"正常"状态,开始按计划调度
- 期望:任务创建后无需其他操作,每天凌晨 2 点自动执行
- 异常处理:
- 如果处理器名称写错了(系统中没有这个 Bean),执行时会报错,日志中会记录"找不到对应的处理器"
- 如果执行失败,会自动重试最多 3 次,每次间隔 5 秒
场景2:运维工程师排查任务失败
- 用户:运维工程师小吴
- 场景:收到站内消息告警"过期订单自动清理 任务执行失败"
- 操作步骤:
- 点击告警消息 → 跳转到定时任务页面
- 找到"过期订单自动清理"任务 → 点击"查看日志"
- 日志列表中看到最新的执行记录,状态为"失败",执行时长 12 秒
- 点击"详情" → 看到失败原因:
Connection refused: database timeout - 进一步查看发现 executeIndex = 4(首次 + 3 次重试都失败了)
- 判断是数据库连接问题 → 检查数据库服务状态 → 恢复数据库
- 回到任务列表 → 点击"执行"手动触发一次 → 确认执行成功
- 期望:日志信息足够详细,能快速定位失败原因
- 为什么这样设计:日志中冗余了 handlerName 和 handlerParam,即使任务后来被修改或删除,历史日志仍能反映当时的执行配置
场景3:开发者调试新处理器
- 用户:后端开发小韩
- 场景:小韩开发了一个新的任务处理器
productStatisticsJob,需要注册并验证 - 操作步骤:
- 在代码中实现
JobHandler接口,注册为 Spring Bean - 部署代码到测试环境
- 进入定时任务管理 → 新增任务
- 处理器名称填
productStatisticsJob - Cron 表达式先填
0 * * * * ?(每分钟执行一次,方便测试) - 保存后点击"执行" → 手动触发一次
- 查看日志 → 确认执行成功,结果数据符合预期
- 修改 Cron 表达式为正式值
0 0 1 * * ?(每天凌晨 1 点)
- 在代码中实现
- 期望:从注册到验证的整个流程快速顺畅,不需要重启服务或改配置文件
场景4:系统升级期间批量暂停任务
- 用户:系统管理员老周
- 场景:数据库迁移期间需要暂停所有与订单相关的定时任务
- 操作步骤:
- 进入定时任务列表
- 搜索"order"相关任务
- 逐个点击"暂停" → 确认
- 数据库迁移完成
- 逐个点击"恢复" → 确认
- 期望:暂停期间任务不会被调度执行,但恢复后自动按 Cron 计划继续执行
- 为什么暂停的任务仍可手动执行:有时候升级后需要手动验证一下任务是否正常,暂停只是停止了自动调度,不禁止手动触发
场景5:验证 Cron 表达式是否正确
- 用户:管理员老周 / 开发小韩
- 场景:配置 Cron 表达式
0 0/15 9-17 * * ?(工作时间每 15 分钟执行一次),不确定是否写得对 - 操作步骤:
- 在 Cron 输入框旁点击"预览"
- 系统展示未来 5 次执行时间:
- 2026-09-19 09:00:00
- 2026-09-19 09:15:00
- 2026-09-19 09:30:00
- 2026-09-19 09:45:00
- 2026-09-19 10:00:00
- 确认符合预期 → 保存
- 期望:不用去网上找 Cron 在线工具验证,系统内直接预览
场景6:任务执行超时告警
- 用户:运维工程师小吴
- 场景:收到告警"支付通知推送 任务执行超时"
- 操作步骤:
- 查看告警详情:任务配置超时阈值 60 秒,实际执行了 180 秒
- 查看日志发现任务虽然最终成功了,但耗时异常
- 分析原因:第三方支付接口响应变慢
- 决策:临时调大超时阈值到 300 秒,同时联系第三方排查接口性能
- 期望:超时告警帮助及时发现系统性能退化,防患于未然
2.3 用户故事
| 编号 | 用户故事 | 优先级 | 验收标准 |
|---|---|---|---|
| US-01 | 作为管理员,我希望能查看所有定时任务列表,以便了解系统有哪些自动化任务 | P0 | ① 支持按任务名称模糊搜索 ② 支持按处理器名称搜索 ③ 支持按状态筛选 ④ 默认按创建时间倒序 ⑤ 响应 < 500ms |
| US-02 | 作为管理员,我希望能创建新的定时任务,以便实现业务自动化 | P0 | ① 表单包含名称、处理器、Cron、重试策略 ② 处理器名称需对应已注册的 Bean ③ 创建后自动同步到调度引擎 ④ 响应 < 1s |
| US-03 | 作为管理员,我希望能暂停/恢复定时任务,以便灵活控制任务执行 | P0 | ① 暂停后不再自动调度 ② 暂停后仍可手动触发 ③ 恢复后按 Cron 继续调度 |
| US-04 | 作为管理员,我希望能手动触发任务执行,以便立即执行或调试任务 | P0 | ① 不受任务状态限制 ② 异步执行,不阻塞页面 ③ 执行过程生成日志 |
| US-05 | 作为管理员,我希望能删除不需要的定时任务,以便清理无效配置 | P0 | ① 删除前需二次确认 ② 同步删除调度引擎中的任务 ③ 不删除已产生的执行日志 |
| US-06 | 作为运维人员,我希望能查看任务执行日志,以便排查任务异常 | P0 | ① 支持按任务编号筛选 ② 支持按状态筛选 ③ 支持按执行时间范围筛选 ④ 日志包含完整执行信息 |
| US-07 | 作为运维人员,我希望能查看日志详情,以便了解完整的执行过程 | P0 | ① 成功时显示处理器返回值 ② 失败时显示异常信息 ③ 显示执行时长和执行序号 |
| US-08 | 作为管理员,我希望能预览 Cron 下次执行时间,以便验证表达式正确性 | P1 | ① 默认展示 5 次 ② 时间格式 yyyy-MM-dd HH:mm:ss ③ 无效表达式返回空列表 |
| US-09 | 作为管理员,我希望能配置任务重试策略,以便提升执行可靠性 | P1 | ① 重试次数 0-10 ② 重试间隔可配置(毫秒)③ 重试耗尽仍失败时记录最终异常 |
| US-10 | 作为管理员,我希望能配置任务超时监控,以便发现执行缓慢的任务 | P1 | ① 超时阈值可配置(毫秒)② 超时后触发告警 ③ 为 0 或空时不监控 |
| US-11 | 作为运维人员,我希望能收到任务异常告警,以便及时发现问题 | P1 | ① 失败告警:重试耗尽仍失败时触发 ② 超时告警:执行时间超过阈值时触发 ③ 同一任务同类型告警有冷却时间 |
| US-12 | 作为管理员,我希望能同步任务配置到调度引擎,以便修复数据不一致 | P1 | ① 将数据库中所有"正常"状态的任务强制同步到 Quartz ② 同步后提示成功 |
| US-13 | 作为系统,同一任务不允许多个实例并发执行 | P0 | ① 使用 @DisallowConcurrentExecution 保障 ② 上一次未执行完时,新触发会等待 |
三、功能需求
3.1 后台管理端 - 任务管理
3.1.1 功能清单
| 功能 | 优先级 | 权限标识 | 说明 |
|---|---|---|---|
| 任务列表 | P0 | infra:job:query | 分页展示任务,支持搜索筛选 |
| 任务详情 | P0 | infra:job:query | 查看单个任务详细信息 |
| 新增任务 | P0 | infra:job:create | 创建新的定时任务 |
| 编辑任务 | P0 | infra:job:update | 修改任务配置 |
| 删除任务 | P0 | infra:job:delete | 删除单个任务 |
| 批量删除 | P2 | infra:job:delete | 批量删除多个任务 |
| 状态切换 | P0 | infra:job:update | 暂停/恢复任务 |
| 立即执行 | P0 | infra:job:trigger | 手动触发任务执行 |
| Cron 预览 | P1 | infra:job:query | 预览下次 N 次执行时间 |
| 任务同步 | P1 | infra:job:create | 同步任务数据到 Quartz |
| 任务导出 | P1 | infra:job:export | 导出任务列表 Excel |
3.1.2 任务列表
页面描述:

业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 默认按创建时间倒序排列 | 最新创建的任务排在前面 |
| R-02 | 支持按任务名称模糊搜索 | 任务多了之后方便快速定位 |
| R-03 | 支持按处理器名称模糊搜索 | 开发者通常知道处理器名称 |
| R-04 | 支持按任务状态筛选 | 方便快速找到暂停或异常的任务 |
| R-05 | 定时任务不受租户隔离限制(@TenantIgnore) | 定时任务是系统级功能,不属于某个租户 |
| R-06 | 删除任务不会删除已产生的执行日志 | 日志是审计依据,即使任务删了也要保留记录 |
数据字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | Long | 任务编号 |
| name | String | 任务名称 |
| status | Integer | 任务状态(0-初始化中 1-正常 2-暂停) |
| handlerName | String | 处理器名称(Spring Bean 名称) |
| handlerParam | String | 处理器参数 |
| cronExpression | String | CRON 表达式 |
| retryCount | Integer | 重试次数 |
| retryInterval | Integer | 重试间隔(毫秒) |
| monitorTimeout | Integer | 监控超时时间(毫秒),0 或空表示不监控 |
| createTime | DateTime | 创建时间 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 获取任务分页 | GET | /admin-api/infra/job/page | 获取定时任务分页列表 |
| 获取任务详情 | GET | /admin-api/infra/job/get | 获取单个定时任务详情 |
请求参数(分页查询):
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | String | 否 | 任务名称(模糊匹配) |
| status | Integer | 否 | 任务状态 |
| handlerName | String | 否 | 处理器名称(模糊匹配) |
| pageNo | Integer | 是 | 页码 |
| pageSize | Integer | 是 | 每页条数 |
3.1.3 新增任务
页面描述:

业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 处理器名称必须对应已注册的 Spring Bean 且实现 JobHandler 接口 | 系统通过 Bean 名称找到处理器并执行,名称不对会报错 |
| R-02 | CRON 表达式必须为合法的 Quartz Cron 格式 | 非法表达式会导致调度异常 |
| R-03 | 重试次数默认 0(不重试),最大 10 | 防止无限重试导致资源浪费 |
| R-04 | 创建成功后自动同步到 Quartz 调度引擎 | 不需要手动"同步"一步,创建即可用 |
| R-05 | 新建任务默认状态为"正常" | 创建后自动开始调度,减少操作步骤 |
处理器类型说明:
| 处理器类型 | 当前状态 | 处理器名称 | 处理器参数 |
|---|---|---|---|
| Spring Bean 调用 | ✅ 已实现 | Spring Bean 名称(如 payNotifyJob) | 传递给 execute 方法的字符串参数 |
| HTTP 调用 | 🔜 规划中 | HTTP URL 地址 | JSON 格式的请求体 |
| 脚本执行 | 🔜 规划中 | 脚本类型标识(如 groovyScript) | 脚本内容或文件路径 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 创建任务 | POST | /admin-api/infra/job/create | 创建新的定时任务 |
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | String | 是 | 任务名称(最多 32 字符) |
| handlerName | String | 是 | 处理器名称(最多 64 字符) |
| handlerParam | String | 否 | 处理器参数(最多 255 字符) |
| cronExpression | String | 是 | CRON 表达式(最多 32 字符) |
| retryCount | Integer | 是 | 重试次数(0-10) |
| retryInterval | Integer | 是 | 重试间隔(毫秒) |
| monitorTimeout | Integer | 否 | 监控超时时间(毫秒) |
返回结果:
| 字段名 | 类型 | 说明 |
|---|---|---|
| data | Long | 新创建的任务编号 |
3.1.4 编辑任务
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 编辑后同步更新 Quartz 调度引擎中的任务配置 | 保证数据库与调度引擎一致 |
| R-02 | 修改 Cron 表达式后,下次执行时间立即按新表达式计算 | 修改即时生效 |
| R-03 | 修改处理器参数后,下次执行将使用新的参数 | 无需重新创建任务 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 更新任务 | PUT | /admin-api/infra/job/update | 更新定时任务配置 |
请求参数: 同创建任务 + id 字段
3.1.5 删除任务
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 删除前需二次确认 | 防止误操作 |
| R-02 | 同步删除 Quartz 调度引擎中的对应任务 | 避免"幽灵任务"继续执行 |
| R-03 | 不删除已产生的执行日志 | 日志是审计依据,独立于任务生命周期 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 删除任务 | DELETE | /admin-api/infra/job/delete | 删除单个定时任务 |
| 批量删除任务 | DELETE | /admin-api/infra/job/delete-list | 批量删除定时任务 |
请求参数(删除):
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 任务编号 |
请求参数(批量删除):
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ids | Long[] | 是 | 任务编号列表 |
3.1.6 状态切换(暂停/恢复)
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 状态枚举:0-初始化中、1-正常、2-暂停 | 三种状态覆盖任务的全部生命周期 |
| R-02 | 切换为"暂停"时,Quartz 暂停该任务的调度 | 暂停后不再自动触发 |
| R-03 | 切换为"正常"时,Quartz 恢复该任务的调度 | 恢复后按 Cron 继续自动执行 |
| R-04 | 暂停中的任务仍可手动触发执行 | 方便维护期间手动验证任务是否正常 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 更新任务状态 | PUT | /admin-api/infra/job/update-status | 更新定时任务状态 |
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 任务编号 |
| status | Integer | 是 | 任务状态(1-正常 2-暂停) |
3.1.7 立即执行
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 不受任务状态限制,暂停状态也可手动触发 | 方便维护期间验证 |
| R-02 | 异步执行,不阻塞前端页面 | 任务可能执行很久,不能让前端一直等 |
| R-03 | 同一任务不允许多个实例并发执行 | 防止并发执行导致数据冲突(如重复清理) |
| R-04 | 如果上次执行尚未完成,新触发会等待 | @DisallowConcurrentExecution 保障 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 触发任务 | PUT | /admin-api/infra/job/trigger | 手动触发定时任务 |
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 任务编号 |
3.1.8 Cron 表达式预览
业务规则:
| 规则编号 | 规则描述 |
|---|---|
| R-01 | 根据 Cron 表达式计算未来 N 次执行时间 |
| R-02 | 默认展示 5 次 |
| R-03 | 无效表达式返回空列表 |
| R-04 | 时间格式为 yyyy-MM-dd HH:mm:ss |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 获取下次执行时间 | GET | /admin-api/infra/job/get_next_times | 获取未来 N 次执行时间 |
请求参数:
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | Long | 是 | 任务编号 |
| count | Integer | 否 | 展示数量,默认 5 |
3.1.9 任务同步
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 将数据库中所有"正常"状态的任务强制同步到 Quartz 调度引擎 | 修复数据库与调度引擎数据不一致的问题 |
| R-02 | 适用场景:服务异常重启、手动修改数据库等导致数据不一致 | 提供一键修复能力 |
| R-03 | 同步操作需要较高权限 | 影响所有任务,需要管理员权限 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 同步任务 | POST | /admin-api/infra/job/sync | 同步定时任务到 Quartz |
3.1.10 任务导出
业务规则:
| 规则编号 | 规则描述 |
|---|---|
| R-01 | 导出当前筛选条件下的全部任务 |
| R-02 | 导出字段:任务编号、任务名称、任务状态、处理器名称、处理器参数、CRON 表达式、监控超时时间、创建时间 |
| R-03 | 任务状态字段使用字典翻译显示中文 |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 导出任务 Excel | GET | /admin-api/infra/job/export-excel | 导出定时任务 Excel |
3.2 后台管理端 - 任务日志
3.2.1 功能清单
| 功能 | 优先级 | 权限标识 | 说明 |
|---|---|---|---|
| 日志列表 | P0 | infra:job:query | 查看任务执行日志 |
| 日志详情 | P0 | infra:job:query | 查看单条日志完整信息 |
| 日志导出 | P1 | infra:job:export | 导出日志 Excel |
| 日志自动清理 | P1 | — | 系统内置任务自动清理过期日志 |
3.2.2 任务日志列表
页面描述:

业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 默认按创建时间倒序排列 | 最新的执行记录排在前面 |
| R-02 | 支持按任务编号筛选 | 快速定位某个任务的所有执行记录 |
| R-03 | 支持按处理器名称模糊搜索 | 方便按处理器类型查找日志 |
| R-04 | 支持按执行时间范围筛选 | 方便定位某个时间段的执行记录 |
| R-05 | 支持按日志状态筛选(运行中/成功/失败) | 快速找到失败的执行记录 |
| R-06 | 日志中的 handlerName 和 handlerParam 为冗余字段 | 即使任务后来被修改或删除,日志仍反映当时的配置 |
数据字段:
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | Long | 日志编号 |
| jobId | Long | 任务编号 |
| handlerName | String | 处理器名称(冗余快照) |
| handlerParam | String | 处理器参数(冗余快照) |
| executeIndex | Integer | 第几次执行(1=首次,>1=重试) |
| beginTime | DateTime | 开始执行时间 |
| endTime | DateTime | 结束执行时间 |
| duration | Integer | 执行时长(毫秒) |
| status | Integer | 日志状态(0-运行中 1-成功 2-失败) |
| result | String | 结果数据(成功时为执行结果,失败时为异常信息) |
接口设计:
| 接口名称 | 请求方式 | 接口路径 | 说明 |
|---|---|---|---|
| 获取日志分页 | GET | /admin-api/infra/job-log/page | 获取任务日志分页列表 |
| 获取日志详情 | GET | /admin-api/infra/job-log/get | 获取单条日志详情 |
请求参数(分页查询):
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| jobId | Long | 否 | 任务编号 |
| handlerName | String | 否 | 处理器名称(模糊匹配) |
| beginTime | DateTime | 否 | 开始执行时间(起始) |
| endTime | DateTime | 否 | 开始执行时间(截止) |
| status | Integer | 否 | 日志状态 |
| pageNo | Integer | 是 | 页码 |
| pageSize | Integer | 是 | 每页条数 |
3.2.3 日志详情
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 成功时 result 字段为处理器 execute 方法的返回值 | 让运维人员知道任务执行的具体结果 |
| R-02 | 失败时 result 字段为异常的根因消息 | 直接展示最核心的错误原因,不用翻完整堆栈 |
| R-03 | 执行序号 > 1 时,页面上标注"重试执行" | 让查看者一眼看出这是重试,不是首次执行 |
3.2.4 日志自动清理
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 由内置定时任务 jobLogCleanJob 自动执行 | 日志会不断积累,需要定期清理释放空间 |
| R-02 | 清理超过指定天数的日志(exceedDay 参数) | 保留近期日志供排查,清理远期日志释放空间 |
| R-03 | 每次清理有数量限制(deleteLimit 参数) | 避免一次性大量删除导致数据库压力 |
| R-04 | 清理操作为物理删除,不可恢复 | 日志量大,逻辑删除没有意义 |
3.2.5 异常告警
业务规则:
| 规则编号 | 规则描述 | 为什么这样设计 |
|---|---|---|
| R-01 | 任务重试次数耗尽后仍失败 → 触发"执行失败告警" | 确保管理员知道有任务彻底失败了 |
| R-02 | 任务执行时长超过 monitorTimeout → 触发"执行超时告警" | 及时发现性能退化 |
| R-03 | monitorTimeout 为 0 或空时,不进行超时监控 | 不是所有任务都需要超时监控 |
| R-04 | 同一任务同一类型告警有冷却时间(建议 5 分钟) | 避免告警风暴(每分钟都报一次"超时") |
| R-05 | 告警通知方式:站内消息(可扩展邮件/钉钉/企微) | 先实现最基础的站内通知,后续按需扩展渠道 |
四、非功能需求
4.1 性能要求
| 指标 | 目标值 | 说明 |
|---|---|---|
| 任务列表查询 | < 500ms | 任务数量通常在百级别 |
| 任务创建/更新 | < 1s | 包含同步到 Quartz 调度引擎的时间 |
| 日志列表查询 | < 500ms | 日志表数据量较大,需关注索引优化 |
| 任务调度触发延迟 | < 1s | 从触发到开始执行的时间 |
| 日志异步更新延迟 | < 5s | 从执行完成到日志更新完毕 |
| 日志清理单批次 | < 30s | 避免清理操作本身影响系统性能 |
4.2 安全要求
| 安全项 | 实现方式 | 说明 |
|---|---|---|
| 权限控制 | 任务管理操作需对应权限标识 | 防止未授权用户操作定时任务 |
| 并发安全 | @DisallowConcurrentExecution | 同一任务不允许多实例并发执行 |
| 操作审计 | 所有管理操作记录操作日志 | 可追溯谁在什么时候修改了什么 |
| 脚本安全(规划中) | 沙箱环境运行 | 未来支持脚本执行时,需限制系统资源访问 |
4.3 可靠性要求
| 要求 | 说明 |
|---|---|
| 调度引擎持久化 | Quartz 调度数据持久化到数据库,服务重启后自动恢复 |
| 任务状态一致性 | 数据库中的任务状态与 Quartz 调度引擎状态保持一致 |
| 日志不丢失 | 任务执行日志必须记录,即使更新失败也不影响日志创建 |
| 故障恢复 | 服务宕机期间错过的调度任务,恢复后按 Cron 表达式自动补偿执行 |
4.4 兼容性要求
| 端 | 要求 |
|---|---|
| PC 浏览器 | Chrome 80+、Firefox 75+、Safari 13+、Edge 80+ |
五、数据设计
5.1 数据模型
定时任务表(infra_job)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 任务编号 |
| name | VARCHAR(32) | NOT NULL | 任务名称 |
| status | TINYINT | NOT NULL | 任务状态(0-初始化中 1-正常 2-暂停) |
| handler_name | VARCHAR(64) | NOT NULL | 处理器名称 |
| handler_param | VARCHAR(255) | NULL | 处理器参数 |
| cron_expression | VARCHAR(32) | NOT NULL | CRON 表达式 |
| retry_count | INT | NOT NULL, DEFAULT 0 | 重试次数 |
| retry_interval | INT | NOT NULL, DEFAULT 0 | 重试间隔(毫秒) |
| monitor_timeout | INT | NOT NULL, DEFAULT 0 | 监控超时时间(毫秒) |
| creator | VARCHAR(64) | DEFAULT '' | 创建者 |
| create_time | DATETIME | NOT NULL | 创建时间 |
| updater | VARCHAR(64) | DEFAULT '' | 更新者 |
| update_time | DATETIME | NOT NULL | 更新时间 |
| deleted | BIT(1) | NOT NULL, DEFAULT 0 | 删除标记 |
租户隔离说明:该表标注
@TenantIgnore,不受多租户隔离限制,属于系统全局数据。
定时任务日志表(infra_job_log)
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| id | BIGINT | PK, AUTO_INCREMENT | 日志编号 |
| job_id | BIGINT | NOT NULL | 任务编号 |
| handler_name | VARCHAR(64) | NOT NULL | 处理器名称(冗余快照) |
| handler_param | VARCHAR(255) | NULL | 处理器参数(冗余快照) |
| execute_index | TINYINT | NOT NULL, DEFAULT 1 | 第几次执行(1=首次,>1=重试) |
| begin_time | DATETIME | NOT NULL | 开始执行时间 |
| end_time | DATETIME | NULL | 结束执行时间 |
| duration | INT | NULL | 执行时长(毫秒) |
| status | TINYINT | NOT NULL | 日志状态(0-运行中 1-成功 2-失败) |
| result | VARCHAR(4000) | NULL | 结果数据 |
| creator | VARCHAR(64) | DEFAULT '' | 创建者 |
| create_time | DATETIME | NOT NULL | 创建时间 |
| updater | VARCHAR(64) | DEFAULT '' | 更新者 |
| update_time | DATETIME | NOT NULL | 更新时间 |
| deleted | BIT(1) | NOT NULL, DEFAULT 0 | 删除标记 |
索引设计:
| 索引名 | 字段 | 类型 | 说明 |
|---|---|---|---|
| idx_job_id | job_id | 普通索引 | 按任务编号查询日志 |
| idx_create_time | create_time | 普通索引 | 按时间范围查询/清理日志 |
5.2 数据关系

为什么日志要冗余 handlerName 和 handlerParam:任务创建后可能被修改(比如换了处理器),甚至被删除。如果日志只存 job_id 关联,那查日志时看到的是修改后的处理器信息,而不是执行当时的。冗余字段保证了日志的"历史真实性"。
5.3 数据字典
| 字典类型 | 字典标识 | 字典值 | 说明 |
|---|---|---|---|
| 定时任务状态 | infra_job_status | 0-初始化中、1-正常、2-暂停 | 任务状态 |
| 任务日志状态 | infra_job_log_status | 0-运行中、1-成功、2-失败 | 日志状态 |
六、跨模块联动
6.1 联动关系总览
| 联动模块 | 联动方式 | 说明 |
|---|---|---|
| 支付模块 | 提供定时处理器 | payNotifyJob(支付通知推送)、payOrderSyncJob(订单同步)、payOrderExpireJob(订单过期处理) |
| 商城交易 | 提供定时处理器 | tradeOrderAutoCancelJob(自动取消)、tradeOrderAutoReceiveJob(自动收货)、tradeOrderAutoCommentJob(自动评价) |
| 商城营销 | 提供定时处理器 | couponExpireJob(优惠券过期)、combinationRecordExpireJob(拼团过期) |
| 商城分销 | 提供定时处理器 | brokerageRecordUnfreezeJob(佣金解冻) |
| 日志审计 | 日志清理 | accessLogCleanJob(访问日志清理)、errorLogCleanJob(错误日志清理) |
| 消息通知 | 告警发送 | 任务失败/超时时通过消息通知模块发送告警 |
| 数据字典 | 字典数据 | 提供任务状态、日志状态的字典翻译 |
6.2 关键联动流程
任务执行全流程

告警通知流程

6.3 已注册的处理器清单
| 处理器名称 | 所属模块 | 功能描述 | 典型 Cron |
|---|---|---|---|
| payNotifyJob | 支付 | 支付通知推送 | 0 * * * * ?(每分钟) |
| payOrderSyncJob | 支付 | 支付订单同步 | 0 * * * * ? |
| payOrderExpireJob | 支付 | 支付订单过期处理 | 0 * * * * ? |
| tradeOrderAutoCancelJob | 商城交易 | 交易订单自动取消 | 0 * * * * ? |
| tradeOrderAutoReceiveJob | 商城交易 | 交易订单自动收货 | 0 0 * * * ?(每小时) |
| tradeOrderAutoCommentJob | 商城交易 | 交易订单自动评价 | 0 0 * * * ? |
| brokerageRecordUnfreezeJob | 商城分销 | 佣金记录解冻 | 0 0 1 * * ? |
| accessLogCleanJob | 基础设施 | 访问日志清理 | 0 0 0 * * ? |
| errorLogCleanJob | 基础设施 | 错误日志清理 | 0 0 0 * * ? |
| jobLogCleanJob | 基础设施 | 任务日志清理 | 0 0 0 * * ? |
| productStatisticsJob | 商城统计 | 商品统计数据 | 0 0 1 * * ? |
| couponExpireJob | 商城营销 | 优惠券过期处理 | 0 0 0 * * ? |
| combinationRecordExpireJob | 商城营销 | 拼团记录过期处理 | 0 0 0 * * ? |
七、附录
7.1 名词解释
| 术语 | 通俗解释 |
|---|---|
| 定时任务 | 设定好时间规则后,系统自动重复执行的任务。就像设了闹钟,到点自动响 |
| Quartz | Java 世界最流行的任务调度框架,PMForge 的定时任务功能就是基于它构建的 |
| Cron 表达式 | 一种时间描述格式,能精确表达"什么时候执行"。比如 0 0 2 * * ? 表示"每天凌晨 2 点" |
| 处理器(JobHandler) | 实际干活的那个"工人"——开发者写的一段 Java 代码,定时任务到点后就调用它来执行具体业务 |
| 处理器名称 | 处理器的"工号"——Spring Bean 的名字。系统通过这个名字找到对应的处理器 |
| 重试 | 任务执行失败后,系统自动再试一次。就像网络不好提交表单失败了,自动帮你再提交 |
| 重试间隔 | 两次重试之间等多久。等 5 秒再试,给系统一个恢复的时间 |
| 监控超时 | 给任务设定一个"预计最长执行时间",超过了就报警。不是停止任务,而是通知管理员"这个任务跑得比平时慢" |
| executeIndex | 第几次执行的编号。1 表示首次执行,2 表示第一次重试,3 表示第二次重试…… |
| @DisallowConcurrentExecution | Quartz 的一个约束——同一个任务在上一次还没执行完的时候,不会启动新的执行。防止"一个任务跑两份"导致数据冲突 |
| 调度引擎 | 就是 Quartz 本身。它负责"到点了就叫醒任务去执行",类似闹钟的机芯 |
| 任务同步 | 把数据库中存的任务配置"刷"一遍到 Quartz 调度引擎里。当两者数据不一致时(比如服务异常重启后),用这个功能修复 |
| JobDataMap | Quartz 存储任务参数的"小本本"——记录了任务 ID、处理器名称、参数、重试配置等信息 |
7.2 Cron 表达式常用示例
| 表达式 | 说明 | 典型场景 |
|---|---|---|
0 * * * * ? | 每分钟 | 支付状态同步、通知推送 |
0 0/5 * * * ? | 每 5 分钟 | 数据缓存刷新 |
0 0/30 * * * ? | 每 30 分钟 | 中间件状态检查 |
0 0 0 * * ? | 每日凌晨 0 点 | 日志清理、数据统计 |
0 0 2 * * ? | 每日凌晨 2 点 | 订单清理、数据备份 |
0 0 0 ? * MON | 每周一凌晨 0 点 | 周报生成 |
0 0 0 1 * ? | 每月 1 号凌晨 0 点 | 月度统计、账单生成 |
7.3 接口汇总
| 接口名称 | 请求方式 | 接口路径 | 权限标识 | 说明 |
|---|---|---|---|---|
| 获取任务分页 | GET | /admin-api/infra/job/page | infra:job:query | 任务列表 |
| 获取任务详情 | GET | /admin-api/infra/job/get | infra:job:query | 任务详情 |
| 创建任务 | POST | /admin-api/infra/job/create | infra:job:create | 新增任务 |
| 更新任务 | PUT | /admin-api/infra/job/update | infra:job:update | 编辑任务 |
| 删除任务 | DELETE | /admin-api/infra/job/delete | infra:job:delete | 删除任务 |
| 批量删除任务 | DELETE | /admin-api/infra/job/delete-list | infra:job:delete | 批量删除 |
| 更新任务状态 | PUT | /admin-api/infra/job/update-status | infra:job:update | 暂停/恢复 |
| 触发任务 | PUT | /admin-api/infra/job/trigger | infra:job:trigger | 立即执行 |
| 同步任务 | POST | /admin-api/infra/job/sync | infra:job:create | 同步到 Quartz |
| 预览执行时间 | GET | /admin-api/infra/job/get_next_times | infra:job:query | Cron 预览 |
| 导出任务 | GET | /admin-api/infra/job/export-excel | infra:job:export | 导出 Excel |
| 获取日志分页 | GET | /admin-api/infra/job-log/page | infra:job:query | 日志列表 |
| 获取日志详情 | GET | /admin-api/infra/job-log/get | infra:job:query | 日志详情 |
| 导出日志 | GET | /admin-api/infra/job-log/export-excel | infra:job:export | 导出 Excel |
7.4 权限配置建议
| 权限标识 | 说明 | 推荐角色 |
|---|---|---|
| infra:job:query | 查看定时任务和日志 | 后台管理员、运维人员 |
| infra:job:create | 创建任务、同步任务 | 系统管理员 |
| infra:job:update | 编辑任务、暂停/恢复 | 系统管理员 |
| infra:job:delete | 删除任务 | 系统管理员 |
| infra:job:trigger | 手动触发任务 | 系统管理员、运维人员 |
| infra:job:export | 导出任务和日志 | 后台管理员、运维人员 |
7.5 变更记录
| 版本 | 日期 | 修改内容 | 修改人 |
|---|---|---|---|
| v1.0 | 2026-09-24 | 初始版本 | PM Team |
| v2.0 | 2026-09-19 | 全面增强:补充业务场景与人物画像、增加验收标准、新增 ASCII 页面原型、补充跨模块联动、新增名词解释、增加设计 rationale、整合处理器清单 | PM Team |
本文档为定时任务模块 PRD v2.0,如有问题请联系产品负责人。