异步与定时任务
StackRivet 区分两件看似相似、但边界不同的事:
- 异步任务——“提交即跑”的重任务:导入、导出、代码生成写入、资产处理。关注的是状态机、幂等、取消、重试、超时和错误分类。
- 定时任务——cron / 固定频率:可视化任务管理、集群防重、手动触发、重试、告警和审计。
重任务永不阻塞请求线程。它作为任务提交,并通过状态机追踪:
stateDiagram-v2 [*] --> pending pending --> running pending --> cancelled running --> success running --> failed failed --> retrying retrying --> running running --> cancelled success --> [*] cancelled --> [*]
每个任务都带 idempotencyKey,使重试不会把活干两遍,外加重试、取消、超时和错误分类。stackrivet-task 模块拥有这套状态机,管理端提供 /tasks 页面,用于筛选、提交、运行、取消、重试和查看任务详情。
这正是为什么导入、导出、生成器写入在架构中被列为异步任务——一个 50 MB 的导入或一次大导出,绝不能占着 web 线程。
定时任务:框架无关的 SPI
Section titled “定时任务:框架无关的 SPI”调度与任何特定调度框架解耦。stackrivet-task 模块定义了一个小的 Scheduler SPI——ScheduledJobHandler、ScheduledJobContext、ScheduledJobResult、ScheduledJobRegistry、SchedulerAdapter、SchedulerCapability——业务 job 只依赖这些 StackRivet 接口,绝不依赖第三方调度器的 API。
默认发行物只内嵌 StackRivet 自己的调度抽象,外加一个本地调度桥,按 handler 名分发任务(并在执行边界恢复租户上下文)。默认运行时不含任何 GPL 组件——早期一次 XXL-Job 试验被撤销,正是因为 XXL-Job 是 GPL-3.0,而 StackRivet 是 Apache-2.0 且带商业 Enterprise 版。
SnailJob 作为企业适配器
Section titled “SnailJob 作为企业适配器”分布式调度方面,SnailJob(Apache-2.0)是优先适配器,作为可选模块发布(stackrivet-scheduler-snailjob)。它:
- 仅当
stackrivet.scheduler.snailjob.enabled=true时才激活——即使 jar 在 classpath 上,缺省也休眠。 - 不进入基础运行时:
stackrivet-app不依赖它,因此默认依赖树里零调度框架代码。 - 是一个把 SnailJob 回调映射到同一个
SchedulerAdapterSPI 的桥,叠加分布式重试、重放治理、告警和控制台。
PowerJob(复杂 DAG / MapReduce)和 ElasticJob(已有 ZooKeeper 的客户)作为进一步的可选适配器;XXL-Job 仅作迁移/外部触发文档,永不作为 StackRivet 依赖。
Scheduler SPI、本地任务样例和 /tasks 管理页在 Community 内。SnailJob 适配器与分布式重试 / 重放治理属于 Pro / Enterprise——见价格页。因为 SPI 在 Community 内,你的 job 代码从第一天就写在 StackRivet 接口之上,日后无需改动即可获得分布式调度。