QuartzScheduler 调度器如何使用

  最近遇到一个需要自动化训练的需求,用户将训练的要求存入库中,例如:每2天晚上9点训练一次。需要根据不同的要求发送训练命令,

经过调研最终选择使用调度器来实现

<!--Quartz-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-quartz -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

1、写一个自动化迭代的类

复制代码
package cn.com.wind.schedule;

import cn.com.wind.config.EsConfig;
import cn.com.wind.config.TranspondProperties;
import cn.com.wind.controller.dto.CommonResp;
import cn.com.wind.repository.elasticsearch.ESComponent;
import cn.com.wind.service.nlp.TrainService;
import cn.com.wind.service.nlp.entity.AutoIterationReq;
import cn.com.wind.service.nlp.entity.SubmitRequest;
import cn.com.wind.util.DateUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import javax.annotation.Resource;
import java.text.MessageFormat;

import static cn.com.wind.utils.TranspondUtils.doPost;


/**
 * @Author qymeng
 * @Date 2022/5/24
 * @Description
 */
@Slf4j
public class AutoIteration extends QuartzJobBean {

    @Resource
    private ESComponent esComponent;

    @Resource
    private EsConfig esConfig;

    @Resource
    private TrainService trainService;

    @Resource
    private TranspondProperties properties;


    /**
     * 自动化迭代
     * @param jobExecutionContext
     */
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) {
        JobDataMap jobDataMap = jobExecutionContext.getMergedJobDataMap();
        AutoIterationReq request = JSONObject.parseObject(JSON.toJSONString(jobDataMap), AutoIterationReq.class);

        if (!request.isWork()) {
            log.info("无需自动迭代");
        }
        String projectName = request.getProjectName();
        String businessName = request.getBusinessName();
        String modelVersion = request.getModelVersion();
        CommonResp<SubmitRequest> businessConfigInfo = trainService.getBusinessConfigInfo(projectName, businessName, modelVersion);
        SubmitRequest submitRequest = businessConfigInfo.getData();
        String ip = MessageFormat.format(properties.getTrainUrl(), submitRequest.getIp());
        //重置样本数量
        JSONObject dataSources = submitRequest.getData_sources();
        dataSources.put("num", request.getSampleNum());
        submitRequest.setData_sources(dataSources);

        JSONObject jsonResult = JSONObject.parseObject(doPost(submitRequest, ip));
        if (jsonResult.getString("msg").equals("操作成功")) {
            log.info(projectName + "任务({})发送成功,发送地址:{}", businessName, ip);
        }
        modelVersion = jsonResult.getString("model_version");
        //在配置信息中增加版本号
        submitRequest.setModel_version(jsonResult.getString("model_version"));
        submitRequest.setCreate_time(DateUtils.nowTime());
        String id = projectName + "_" + businessName + "_" + modelVersion;
        //存储配置信息入es
        esComponent.addData(submitRequest, esConfig.getNlpIndex(), esConfig.getNlpBusinessConfig(), id);
        log.info("自动化迭代训练已发送");
    }


}
复制代码

 

2、完成一个调度器的实现,注意类名不能使用QuartzScheduler,否则会重名

复制代码

package cn.com.wind.schedule;


import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;


/**
* @Author qymeng
* @Date 2022/5/24
* @Description
*/
@Component
@Slf4j
public class QuartzSchedulerTemp {

@Autowired
private Scheduler scheduler;

/**
* 执行调度任务
* @param cron
* @param id
* @param jobDataMap
* @throws SchedulerException
*/
public void startJob(String cron, String id, JobDataMap jobDataMap) throws SchedulerException {
JobDetail jobDetail = JobBuilder.newJob(AutoIteration.class)
.setJobData(jobDataMap)
.withIdentity(id).build();

//基于表达式构建触发器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);

CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(id)
.withSchedule(cronScheduleBuilder).build();
scheduler.scheduleJob(jobDetail, cronTrigger);
if (!scheduler.isShutdown()){
scheduler.start();
}
}

/**
* 删除所有调度任务
* @throws SchedulerException
*/
public void deleteAllJob() throws SchedulerException {
GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
Set<JobKey> jobKeys = scheduler.getJobKeys(matcher);
for(JobKey jobKey:jobKeys){
scheduler.deleteJob(jobKey);
}
}
}
 
复制代码

 

 

3、设置一个Scheduled定时器,从库中将cron表达式和请求体存入调度器中,并启动调度器

复制代码
@Autowired
QuartzSchedulerTemp quartzSchedulerTemp;

/**
* 定时器每天拉取配置放入调度器中
*/
@Async
@Scheduled(cron = "0 59 0/1 * * ? ")
public void autoIteration() {
try {
quartzSchedulerTemp.deleteAllJob();
} catch (SchedulerException e) {
log.error("删除所有动态sql定时任务失败");
}
List<Map<String, Object>> recordList = esComponent.searchDataPage(esConfig.getNlpIndex(), esConfig.getNlpAutoIteration()).getRecordList();
if (recordList != null && recordList.size() != 0){

for (Map<String, Object> map : recordList) {
JobDataMap jobDataMap = new JobDataMap(map);
String cron = map.get("cron").toString();
String businessName = map.get("businessName").toString();
try {
log.info("启动自动迭代定时任务,cron:{}, businessName:{}",cron, businessName);
quartzSchedulerTemp.startJob(cron, businessName, jobDataMap);
}catch (Exception e){
log.error("启动定时任务失败!", e);
}
}
}

}
复制代码

 

QuartzScheduler
posted @   Mikey-  阅读(257)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示