Furion.Pure 定时任务调度

定时任务调度

一、核心功能

定时任务调度是 Furion.Pure 框架提供的轻量级作业调度系统,支持多种触发方式和分布式部署。

1.1 核心价值

  • 多种触发方式:支持 Cron 表达式、周期触发、一次性触发等
  • 分布式支持:支持集群部署,避免任务重复执行
  • 可视化管理:提供 Web Dashboard 管理界面
  • 持久化存储:支持任务执行记录持久化
  • 灵活配置:支持属性配置和代码配置

二、触发方式

2.1 Cron 表达式触发

使用 [Cron] 特性配置 Cron 表达式:

csharp 复制代码
[Cron("0 0 2 * * ?")]
public class DailyReportJob : IJob
{
    public async Task ExecuteAsync(JobExecutingContext context)
    {
        // 每天凌晨 2 点执行
    }
}

2.2 周期触发

使用 [Period] 特性配置固定周期:

csharp 复制代码
[Period(Seconds = 60)]
public class HeartbeatJob : IJob
{
    public async Task ExecuteAsync(JobExecutingContext context)
    {
        // 每 60 秒执行一次
    }
}

2.3 快捷周期特性

框架提供了多种快捷周期特性:

特性 说明
[Secondly] 每秒执行
[Minutely] 每分钟执行
[Hourly] 每小时执行
[Daily] 每天执行
[Weekly] 每周执行
[Monthly] 每月执行
[Yearly] 每年执行

2.4 指定时间触发

使用 [DailyAt][HourlyAt] 等特性指定具体时间:

csharp 复制代码
[DailyAt("08:00", "18:00")]
public class WorkTimeJob : IJob
{
    public async Task ExecuteAsync(JobExecutingContext context)
    {
        // 每天 8 点和 18 点执行
    }
}

三、实现流程

3.1 服务注册

Startup.cs 中调用:

csharp 复制代码
services.AddSchedule();

注册逻辑

步骤 操作 说明
1 构建调度器配置 创建 ScheduleOptionsBuilder
2 注册日志服务 添加 IScheduleLogger
3 注册调度器工厂 添加 ISchedulerFactory
4 注册取消 Token 添加 IJobCancellationToken
5 注册后台服务 添加 ScheduleHostedService

3.2 作业执行流程

复制代码
┌─────────────────────────────────────────────────────────────┐
│                    调度器启动阶段                           │
├─────────────────────────────────────────────────────────────┤
│  1. ScheduleHostedService 启动                              │
│     └── 创建调度器实例                                      │
├─────────────────────────────────────────────────────────────┤
│  2. 扫描所有实现 IJob 的类                                   │
│     └── 注册到调度器                                        │
├─────────────────────────────────────────────────────────────┤
│  3. 根据触发配置计算下次执行时间                              │
│     └── 注册到触发器队列                                    │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│                    作业执行阶段                             │
├─────────────────────────────────────────────────────────────┤
│  1. 触发器触发                                              │
│     └── 创建作业执行上下文                                   │
├─────────────────────────────────────────────────────────────┤
│  2. 调用作业执行器                                          │
│     └── 执行 IJob.ExecuteAsync()                            │
├─────────────────────────────────────────────────────────────┤
│  3. 记录执行结果                                            │
│     └── 更新持久化存储                                       │
└─────────────────────────────────────────────────────────────┘

四、作业上下文

JobExecutingContext 提供了丰富的上下文信息:

csharp 复制代码
public class JobExecutingContext
{
    /// <summary>
    /// 作业 ID
    /// </summary>
    public string JobId { get; }
    
    /// <summary>
    /// 作业名称
    /// </summary>
    public string JobName { get; }
    
    /// <summary>
    /// 触发类型
    /// </summary>
    public TriggerType TriggerType { get; }
    
    /// <summary>
    /// 执行次数
    /// </summary>
    public int ExecuteCount { get; }
    
    /// <summary>
    /// 取消 Token
    /// </summary>
    public CancellationToken CancellationToken { get; }
    
    /// <summary>
    /// 作业参数
    /// </summary>
    public object[] Arguments { get; }
}

五、配置选项

ScheduleOptionsBuilder 提供了丰富的配置项:

配置项 默认值 说明
ClusterId null 集群 ID,用于分布式部署
LogEnabled true 是否启用日志
UnobservedTaskExceptionHandler null 未处理异常处理器

5.1 配置示例

csharp 复制代码
services.AddSchedule(options =>
{
    options.ClusterId = "cluster-001";
    options.LogEnabled = true;
    options.UnobservedTaskExceptionHandler = (sender, args) =>
    {
        // 处理未观察到的异常
    };
});

六、高级特性

6.1 分布式部署

配置 ClusterId 实现分布式部署:

csharp 复制代码
services.AddSchedule(options =>
{
    options.ClusterId = "production-cluster";
});

框架会自动协调集群中的任务执行,确保同一任务只在一个节点上执行。

6.2 作业参数

通过特性传递参数:

csharp 复制代码
[JobDetail(Arguments = new object[] { "param1", 123 })]
[Cron("0 0 * * * ?")]
public class ParameterizedJob : IJob
{
    public async Task ExecuteAsync(JobExecutingContext context)
    {
        var param1 = context.Arguments[0] as string;
        var param2 = (int)context.Arguments[1];
    }
}

6.3 作业监控

实现 IJobMonitor 接口监控作业执行:

csharp 复制代码
public class JobMonitor : IJobMonitor
{
    public void OnExecuting(JobExecutingContext context)
    {
        // 作业开始执行
    }
    
    public void OnExecuted(JobExecutedContext context)
    {
        // 作业执行完成
    }
}

6.4 持久化存储

实现 IJobPersistence 接口自定义持久化存储:

csharp 复制代码
public class CustomJobPersistence : IJobPersistence
{
    public Task SaveExecutionRecordAsync(JobExecutionRecord record)
    {
        // 保存执行记录
    }
    
    public Task<List<JobExecutionRecord>> GetExecutionRecordsAsync(string jobId)
    {
        // 获取执行记录
    }
}

6.5 动态作业

支持动态创建和注册作业:

csharp 复制代码
public class JobController
{
    private readonly ISchedulerFactory _schedulerFactory;
    
    public JobController(ISchedulerFactory schedulerFactory)
    {
        _schedulerFactory = schedulerFactory;
    }
    
    public void AddJob()
    {
        var scheduler = _schedulerFactory.Create();
        scheduler.Schedule<MyDynamicJob>()
                 .Cron("0 0 1 * * ?")
                 .Build();
    }
}

七、Dashboard

框架提供了 Web Dashboard 用于可视化管理作业:

7.1 启用 Dashboard

csharp 复制代码
services.AddSchedule(options =>
{
    options.UseDashboard();
});

7.2 访问地址

默认访问地址:http://localhost:5000/schedule

7.3 Dashboard 功能

功能 说明
作业列表 查看所有已注册的作业
执行记录 查看作业执行历史
手动触发 手动触发作业执行
暂停/恢复 暂停或恢复作业

八、核心文件

文件 说明
ScheduleServiceCollectionExtensions.cs 调度服务扩展方法
IJob.cs 作业接口
IScheduler.cs 调度器接口
ISchedulerFactory.cs 调度器工厂接口
Trigger.cs 触发器基类
CronTrigger.cs Cron 表达式触发器
PeriodTrigger.cs 周期触发器
JobExecutingContext.cs 作业执行上下文
ScheduleHostedService.cs 调度后台服务
ScheduleLogger.cs 调度日志服务

九、总结

定时任务调度通过灵活的触发配置和强大的扩展能力,实现了轻量级的作业调度系统。核心设计思想:

  1. 声明式配置:通过特性声明作业触发规则,无需手动注册
  2. 多触发方式:支持 Cron 表达式、周期触发、指定时间触发等多种方式
  3. 分布式支持:内置集群协调机制,支持分布式部署
  4. 可视化管理:提供 Web Dashboard 便于监控和管理
  5. 高度可扩展:支持自定义持久化、监控和触发器

这种设计使得开发者可以轻松实现定时任务,无需引入复杂的第三方调度框架。

相关推荐
包达叔2 年前
Furion项目的单元测试
单元测试·furion