[061][调度模块]领域驱动的任务调度架构设计与分层实践

简介: 本文介绍基于领域驱动设计(DDD)的六边形调度架构:解耦核心调度逻辑与基础设施,通过Task接口统一抽象、事件驱动日志、Specification动态查询及JSON元数据灵活扩展;采用Record+Builder保障不可变传输,Repository适配器屏蔽ORM细节,全面提升可维护性与可扩展性。(239字)

[061][调度模块]领域驱动的任务调度架构设计与分层实践

1. 整体架构蓝图

该模块采用六边形架构思想,将核心领域(调度、日志)与基础设施(数据库、Web)解耦。核心设计决策如下:

  • 任务定义与运行时分离JobEntity 作为持久化配置,ScheduleTaskManager 管理内存中的执行实例,通过 Task 接口统一抽象。
  • 事件驱动的日志记录:状态变更事件异步触发日志持久化,避免阻塞调度主流程。
  • 规格模式(Specification):动态查询条件组合,避免冗长的 JPQL 拼接。
┌─────────────────────────────────────────────────────────────┐
│                    表示层 (Web)                             │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐ │
│  │ JobEndpoint  │  │ScheduleEndpoint│  │ JobLogEndpoint  │ │
│  └──────────────┘  └──────────────┘  └──────────────────┘ │
└─────────────────────────┬───────────────────────────────────┘
                          │ DTO/VO 转换
┌─────────────────────────▼───────────────────────────────────┐
│                    应用服务层 (Service)                      │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐ │
│  │  JobService  │  │ScheduleService│  │  JobLogService  │ │
│  └──────────────┘  └──────────────┘  └──────────────────┘ │
└─────────────────────────┬───────────────────────────────────┘
                          │ 领域接口
┌─────────────────────────▼───────────────────────────────────┐
│                    领域层 (Domain)                          │
│  ┌────────────────────────────────────────────────────────┐ │
│  │  interface Task  ◄─── implements  ──── JobEntity      │ │
│  │  interface TaskRepository  ◄─── implements ────       │ │
│  │            DatabaseTaskRepository (适配 JPA)          │ │
│  │  interface ChangeStatusEventConsumer ◄─── implements  │ │
│  │            JobLogEventConsumer (事件监听)             │ │
│  └────────────────────────────────────────────────────────┘ │
└─────────────────────────┬───────────────────────────────────┘
                          │ JPA
┌─────────────────────────▼───────────────────────────────────┐
│                    基础设施层 (Infrastructure)               │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐ │
│  │ JobRepository│  │JobLogRepository│  │ ScheduleTask    │ │
│  │  (JPA)       │  │   (JPA)       │  │   Manager       │ │
│  └──────────────┘  └──────────────┘  └──────────────────┘ │
└─────────────────────────────────────────────────────────────┘

2. 核心领域模型:Task 接口与 JobEntity 实现

技术亮点:接口统一 + 多态持久化

Task 接口定义了调度器所需的所有配置方法,JobEntity 通过实现该接口,既可作为 JPA 实体,又能直接注入调度管理器。

// 调度核心定义的任务契约
public interface Task {
   
    String getTaskCode();
    String getClassSimpleName();
    String getCron();
    boolean isEnabled();
    String getDescription();
    Map<String, String> getMetadata();
    Duration getInitialDelay();
    Integer getMaxFailureCount();
    Integer getMaxExecutionCount();
    Instant getDueDate();
}

// 领域实体同时实现接口与 JPA 注解
@Data
@Entity
@Table(name = "feat_job")
public class JobEntity extends BaseStatusEntity implements Task {
   
    @Column(length = 64, unique = true, updatable = false)
    private String taskCode;

    @Column(length = 64)
    private String classSimpleName;

    @Column(length = 64)
    private String cron;

    @JdbcTypeCode(SqlTypes.JSON)  // ✅ 利用 Hibernate 6 的 JSON 映射
    @Column(columnDefinition = "json")
    private Map<String, String> metadata;

    // ... 其他字段

    @Override
    public boolean isEnabled() {
   
        // 利用父类状态字段实现软删除 + 预留双重语义
        return Objects.equals(getDataStatus(), DataStatusEnum.NORMAL)
                || Objects.equals(getDataStatus(), DataStatusEnum.RESERVED);
    }
}

设计精要:

  • JSON 元数据@JdbcTypeCode(SqlTypes.JSON) 自动序列化 Map 为 JSON 列,支持灵活扩展而无需 DDL 变更。
  • 状态语义NORMAL 为正常启用,RESERVED 为保留(可被特殊逻辑触发),DELETED 为逻辑删除,丰富了生命周期管理。

3. 仓库适配层:DatabaseTaskRepository 的防腐作用

技术亮点:适配器模式隔离 ORM 依赖

@Service
@RequiredArgsConstructor
public class DatabaseTaskRepository implements TaskRepository<JobEntity> {
   
    private final JobRepository jobRepository;  // Spring Data JPA

    @Override
    public Optional<JobEntity> findByTaskCode(String taskCode) {
   
        return jobRepository.findByTaskCode(taskCode);
    }

    @Override
    public List<JobEntity> findAll() {
   
        return jobRepository.findAll();
    }
}

通过实现 TaskRepository 接口,上层 ScheduleService 完全不知晓 JPA 的存在。若将来迁移至 MyBatis 或 Redis,只需替换该适配类,业务逻辑零修改。

4. 不可变数据传输:Record + Builder 模式

TaskExecutionDetails 使用 @Builder 注解构建不可变对象,聚合任务定义与运行时状态:

@Builder
public record TaskExecutionDetails(
    String taskCode,          // 任务标识
    String classSimpleName,   // 执行类
    String cron,              // 调度表达式
    boolean enabled,          // 是否启用
    String description,       // 描述
    Map<String, String> metadata,  // 扩展属性(不可变视图)
    Duration initialDelay,
    Integer maxFailureCount,
    Integer maxExecutionCount,
    Instant dueDate,
    // 以下为运行时动态数据
    TaskStatusEnum taskStatus,
    String lotNo,
    int totalCount,
    int totalFailureCount,
    Instant startTime,
    Instant endTime,
    String message,
    Throwable throwable
) {
   }

技术亮点:

  • Record 不可变性:天然线程安全,适合多线程环境下的数据传递。
  • Builder 模式:支持部分字段构建,结合 MapUtils.unmodifiableMap 保证元数据只读。
目录
相关文章
|
22天前
|
存储 缓存 NoSQL
[032][缓存模块]基于Redis Bitmap的用户行为统计实战:签到与日活分析
本文详解如何用Redis Bitmap实现高效用户行为统计:基于Spring Boot,通过`RedisBitmapUtils`封装位图操作(设位、计数、AND/OR运算),配合`UserActivityController`提供签到、DAU、连续N日/周活跃等API。空间极省、查询毫秒级,适合亿级用户场景。(239字)
99 2
SQL Serverless 数据库连接
23 1
人工智能 开发框架 Java
42 5
存储 关系型数据库 MySQL
29 0
弹性计算 小程序 iOS开发
31 2
|
30天前
|
存储 人工智能 安全
从RAG到知识图谱:企业AI知识库的技术范式革命与未来十年路线图
本文从CTO视角剖析企业AI知识库的技术范式革命:RAG正经历三代跃迁,迈向多跳推理与自适应检索;知识图谱在大模型时代强势复兴,实现文件关联、专家发现与影响分析;架构上加速向多云融合、跨平台统一数据层及新私有化演进;管理上推动知识全生命周期、物理级隔离与价值量化。未来十年,知识库将升维为战略资产。(239字)
224 0
|
消息中间件 Java Kafka
什么是Apache Kafka?如何将其与Spring Boot集成?
什么是Apache Kafka?如何将其与Spring Boot集成?
950 5

热门文章

最新文章