〇、相关资料

1、cola架构分层参考

COLA 4.0:应用架构的最佳实践_cola4.0-CSDN博客

2、spring定时任务与线程池配置

spring定时任务Scheduled与定时任务线程池配置SchedulingConfigurer ,Java_自定义spring schedule线程池-CSDN博客


一、概览

1.1 代码框架

Spring Boot项目+Schedule完成批量定时任务调用的最佳实践_最佳实践

1.2 各部分介绍

1、Task:通用任务接口

2、impl.XXTask:具体任务实现类

3、TaskFactory:任务工厂类,维护任务名和任务定义的关系

4、SelfTaskScheduler:任务调度类,完成任务工厂注册和任务调度定义

二、通用任务定义

2.1 接口定义

1、内容

包含无参和有参(String格式的参数,用于解析json)

2、代码

package com.xx.integration.app.scheduler;

/**
 * @Author xx xx
 * @Since 2024/6/4 11:12
 * @Description Task
 */
public interface Task {
    void execute();

    void execute(String param);
}

2.2 实现类

package com.xx.yy.app.scheduler.impl;

import com.alibaba.fastjson.JSONObject;
import com.xx.yy.app.scheduler.Task;
import com.xx.yy.app.utils.DateTimeUtils;
import com.xx.yy.domain.gateway.DbDataSourceGateway;
import com.xx.yy.domain.gateway.alert.ISendDingTalkService;
import com.xx.yy.domain.model.entities.DataSourceDbInfoEntity;
import com.xx.yy.domain.model.enums.MetaDataRecordEnum;
import com.xx.yy.infrastructure.gatewayimpl.DbDataSourceGatewayImpl;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.List;

/**
 * @Author xx xx
 * @Since 2024/6/4 11:14
 * @Description IntelligentMatchStateChekTask
 */
@Service
public class IntelligentMatchStateCheckTask implements Task {
    @Value("${schedule.interval.intelligent-match.state.check:30}")
    private Integer stateCheckInterval;

    @Resource
    private DbDataSourceGateway dbDataSourceGateway;

    @Resource
    private ISendDingTalkService sendDingTalkService;

    @Override
    public void execute() {
        // 遍历ds_db_info
        List<DataSourceDbInfoEntity> dataSourceDbInfoEntityList = dbDataSourceGateway.queryByComputeStatus(MetaDataRecordEnum.ALGORITHM.Stage.BUILDING);
        // 寻找任务状态是进行中&距离当前超过config最大间隔分钟的任务
        for (DataSourceDbInfoEntity dataSourceDbInfoEntity : dataSourceDbInfoEntityList) {
            Timestamp modifyTime = dataSourceDbInfoEntity.getModifyTime();
            boolean afterLargeMinute = DateTimeUtils.isAfterLargeMinute(stateCheckInterval, modifyTime);
            if (afterLargeMinute) {
                // send msg
                sendDingTalkService.send("智能匹配任务" + dataSourceDbInfoEntity.getName() + "超时,将状态更新为失败,请检查执行过程:" + JSONObject.toJSONString(dataSourceDbInfoEntity));
                dbDataSourceGateway.updateEntityBySystemId(DataSourceDbInfoEntity.builder()
                        .dsSystemId(dataSourceDbInfoEntity.getDsSystemId())
                        .modifyTime(DateTimeUtils.getCurrentSqlTimeStamp())
                        .computeStatus(MetaDataRecordEnum.ALGORITHM.Stage.FAILURE)
                        .build());
            }
        }
    }

    @Override
    public void execute(String param) {
        return;
    }
}

三、任务工厂定义

3.1 介绍

用于管理所有的调度任务

实现注册到工厂和从工厂中获取对应的任务定义

3.2 实现

package com.xx.yy.app.scheduler;

import org.apache.hadoop.yarn.webapp.hamlet.Hamlet;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author xx xx
 * @Since 2024/6/4 11:16
 * @Description TaskFactory
 */
@Component
public class TaskFactory {
    private final Map<String, Task> taskMap;

    public TaskFactory(List<Task> taskList) {
        this.taskMap = new HashMap<>();
        for (Task task : taskList) {
            taskMap.put(task.getClass().getSimpleName(), task);
        }
    }

    public Task createTask(String taskName) {
        return this.taskMap.get(taskName);
    }
    
    // todo:可以实现新增task注册方法
}

四、任务调度类

4.1 介绍

1、实现不同调度任务的注册

2、按照不同的调度时间,编写不同的方法,并执行对应的方法

4.2 实现

package com.boulderai.integration.app.scheduler;

import com.boulderai.integration.app.scheduler.impl.IntelligentMatchStateCheckTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @Author Liu Jinhui
 * @Since 2024/6/4 11:22
 * @Description TaskScheduler
 */
@Slf4j
@Component
@EnableScheduling
public class SelfTaskScheduler {
    @Resource
    private TaskFactory taskFactory;

    @Autowired
    public SelfTaskScheduler() {
        List<Task> taskInit = Arrays.asList(new IntelligentMatchStateCheckTask());
        log.info("init {} tasks.", taskInit.size());
        this.taskFactory = new TaskFactory(taskInit);
    }

    @Scheduled(cron = "0 0/10 * * * ?")
    public void tenMinuteScheduleTasks() {
        String intelligentMatchStateCheckTaskName = IntelligentMatchStateCheckTask.class.getSimpleName();
        Task intelligentMatchStateCheckTask = this.taskFactory.createTask(intelligentMatchStateCheckTaskName);
        if (Objects.isNull(intelligentMatchStateCheckTask)) {
            log.info("task {} retrieval failure...", intelligentMatchStateCheckTaskName);
        }
        intelligentMatchStateCheckTask.execute();
    }

}