跳到主要内容
版本:3.0.0

延迟任务队列

3.0.0 页面说明

  • 3.0.0 说明:当前页已重写为 3.x 的任务调度主题页。
  • 推荐阅读顺序:先看当前页选型,再进入对应组件页。

Aegis.Jobs 用来把一段业务逻辑延后执行。最常见的场景是延迟通知、异步补偿、长时间后台任务和递归调度任务。

先做选型

当前这一组建议按下面的方式选:

方案适合什么场景
Aegis.Jobs + Aegis.Jobs.Postgres正式环境,当前 3.x 推荐方案
Aegis.Jobs + Aegis.Jobs.SqlServer必须沿用 SQL Server 的项目

如果你只是要一条默认靠谱的路,直接选 Aegis.Jobs + Aegis.Jobs.Postgres

推荐接入路径

第一步:启用组件

推荐组合:

{
"Components": {
"Services": [
"Jobs",
"Jobs.Postgres"
],
"Middlewares": []
}
}

这里建议保持 Jobs 在前,Jobs.Postgres 在后。

第二步:准备配置

{
"ServerSettings": {
"ServerId": "1"
},
"PostgreConnection": "Host=127.0.0.1;Database=aegis_jobs;Port=5432;Username=postgres;Password=postgres"
}

ServerId 在多实例部署时要唯一。

第三步:开始调度

var jobId = AegisJob.Schedule<TestJob>(
x => x.Test(2),
TimeSpan.FromSeconds(1));

最常见的任务写法

调度静态方法或当前上下文方法

var jobId = AegisJob.Schedule(
() => ChangeUser(id, statusCode),
TimeSpan.FromSeconds(15));

调度服务类实例方法

var jobId = AegisJob.Schedule<UserService>(
x => x.DelayQueueTest(DateTime.Now.Day),
TimeSpan.FromSeconds(30));

调度专门的 Job 类

public class TestJob
{
public Task Test(int times)
{
Console.WriteLine(DateTime.Now);

if (times > 0)
{
AegisJob.Schedule<TestJob>(
x => x.Test(times - 1),
TimeSpan.FromMinutes(1));
}

return Task.CompletedTask;
}
}

这种写法适合递归调度、批处理、长任务。

怎么取消任务

var jobId = AegisJob.Schedule(
() => ChangeUser(id, statusCode),
TimeSpan.FromMinutes(10));

var canceled = AegisJob.Cancel(jobId);

任务状态怎么理解

状态含义
Scheduled已写入存储,等待执行时间到达
Queued已进入执行队列
Processing正在执行
Succeeded执行成功
Failed执行失败
Canceled已取消
Aborted中断退出,等待后续恢复或处理

什么时候要单独建 Job 类

更推荐单独建 Job 类的场景:

  • 任务逻辑很长
  • 任务需要多次递归调度
  • 任务和普通业务服务职责不同
  • 你希望把后台任务和接口服务拆开维护

常见问题

为什么任务调度失败了

优先检查:

  • 目标方法是不是 public
  • 异步方法是不是返回 Task
  • 方法参数里有没有 refout
  • 对应服务或 Job 类能不能被容器正常创建

SQL Server 和 Postgres 该怎么选

默认优先选 Postgres。
只有在数据库环境已经固定为 SQL Server 时,再考虑 SQL Server 扩展。

继续阅读