跳转到内容

异步与定时任务

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 线程。

调度与任何特定调度框架解耦stackrivet-task 模块定义了一个小的 Scheduler SPI——ScheduledJobHandlerScheduledJobContextScheduledJobResultScheduledJobRegistrySchedulerAdapterSchedulerCapability——业务 job 依赖这些 StackRivet 接口,绝不依赖第三方调度器的 API。

默认发行物只内嵌 StackRivet 自己的调度抽象,外加一个本地调度桥,按 handler 名分发任务(并在执行边界恢复租户上下文)。默认运行时不含任何 GPL 组件——早期一次 XXL-Job 试验被撤销,正是因为 XXL-Job 是 GPL-3.0,而 StackRivet 是 Apache-2.0 且带商业 Enterprise 版。

分布式调度方面,SnailJob(Apache-2.0)是优先适配器,作为可选模块发布(stackrivet-scheduler-snailjob)。它:

  • 仅当 stackrivet.scheduler.snailjob.enabled=true 时才激活——即使 jar 在 classpath 上,缺省也休眠。
  • 不进入基础运行时:stackrivet-app 不依赖它,因此默认依赖树里零调度框架代码。
  • 是一个把 SnailJob 回调映射到同一个 SchedulerAdapter SPI 的桥,叠加分布式重试、重放治理、告警和控制台。

PowerJob(复杂 DAG / MapReduce)和 ElasticJob(已有 ZooKeeper 的客户)作为进一步的可选适配器;XXL-Job 仅作迁移/外部触发文档,永不作为 StackRivet 依赖。

Scheduler SPI、本地任务样例和 /tasks 管理页在 Community 内SnailJob 适配器与分布式重试 / 重放治理属于 Pro / Enterprise——见价格页。因为 SPI 在 Community 内,你的 job 代码从第一天就写在 StackRivet 接口之上,日后无需改动即可获得分布式调度。