添加定时任务
This commit is contained in:
parent
3053e71a42
commit
ade6432bf4
9
pom.xml
9
pom.xml
|
|
@ -5,7 +5,7 @@
|
|||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.18</version>
|
||||
<version>2.4.5</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.bonus</groupId>
|
||||
|
|
@ -61,6 +61,13 @@
|
|||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Quartz -->
|
||||
<!-- Spring Boot Quartz Starter -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-quartz</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package com.bonus.emergencyrap.constant;
|
|||
/**
|
||||
* 任务调度通用常量
|
||||
*
|
||||
* @author ruoyi
|
||||
* @author bonus
|
||||
*/
|
||||
public class ScheduleConstants
|
||||
{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
package com.bonus.emergencyrap.task.config;
|
||||
|
||||
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.spi.JobFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
@Configuration
|
||||
public class QuartzConfig {
|
||||
|
||||
@Bean
|
||||
public JobFactory jobFactory() {
|
||||
return new SpringBeanJobFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) {
|
||||
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
|
||||
schedulerFactoryBean.setJobFactory(jobFactory);
|
||||
|
||||
// 配置Quartz使用内存存储
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("org.quartz.scheduler.instanceName", "MyScheduler");
|
||||
properties.setProperty("org.quartz.scheduler.instanceId", "AUTO");
|
||||
properties.setProperty("org.quartz.jobStore.class", "org.quartz.simpl.RAMJobStore");
|
||||
properties.setProperty("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
|
||||
properties.setProperty("org.quartz.threadPool.threadCount", "5");
|
||||
|
||||
schedulerFactoryBean.setQuartzProperties(properties);
|
||||
return schedulerFactoryBean;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Scheduler scheduler(SchedulerFactoryBean schedulerFactoryBean) throws Exception {
|
||||
return schedulerFactoryBean.getScheduler();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package com.bonus.emergencyrap.task.job;
|
||||
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.bonus.emergencyrap.constant.TextConstants;
|
||||
import com.bonus.emergencyrap.utils.TextFileUtils;
|
||||
import com.bonus.emergencyrap.utils.UploadFile;
|
||||
import com.bonus.emergencyrap.vo.TaskVo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 执行任务定时器
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ActuatorJob implements Job {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ActuatorJob.class);
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||
String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
log.info(context.getTrigger().getJobDataMap().get("taskId").toString());
|
||||
String taskId = context.getTrigger().getJobDataMap().get("taskId").toString();
|
||||
//文件进行解析
|
||||
String filePtah= UploadFile.getFilePath(TextConstants.TASK);
|
||||
Map<String,String> map= TextFileUtils.readFileMaps(filePtah);
|
||||
TaskVo vo= JSON.parseObject(map.get(taskId), TaskVo.class);
|
||||
System.err.println(vo.getTaskName());
|
||||
logger.info("SampleJob 执行时间: {}", currentTime);
|
||||
logger.info("任务执行器开始执行,执行任务id=="+vo.getTaskId()+"任务名称是=="+vo.getTaskName()+"执行时间=="+vo.getCorn());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.bonus.emergencyrap.task.job;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.bonus.emergencyrap.constant.TextConstants;
|
||||
import com.bonus.emergencyrap.task.service.QuartzJobService;
|
||||
import com.bonus.emergencyrap.utils.TextFileUtils;
|
||||
import com.bonus.emergencyrap.utils.UploadFile;
|
||||
import com.bonus.emergencyrap.vo.TaskVo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 定时任务扫描
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ScanJob implements Job {
|
||||
|
||||
@Autowired
|
||||
private QuartzJobService service;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext context) throws JobExecutionException {
|
||||
try {
|
||||
String currentTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
|
||||
System.err.println(currentTime);
|
||||
String filePtah= UploadFile.getFilePath(TextConstants.TASK);
|
||||
//文件是否存在
|
||||
boolean isCz= TextFileUtils.exists(filePtah);
|
||||
if(isCz){
|
||||
//文件进行解析
|
||||
Map<String,String> map=TextFileUtils.readFileMaps(filePtah);
|
||||
for (String key : map.keySet()) {
|
||||
TaskVo vo= JSON.parseObject(map.get(key), TaskVo.class);
|
||||
String status=vo.getStatus();
|
||||
//关闭直接删除
|
||||
if("0".equals(status)){
|
||||
service.deleteJob(vo);
|
||||
}else{
|
||||
//添加或者修改定时任务
|
||||
service.addTask(vo);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.err.println(context.getTrigger().getJobDataMap().get("taskId"));
|
||||
log.info("定时任务扫描中scan....");
|
||||
} catch (Exception e) {
|
||||
throw new JobExecutionException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.bonus.emergencyrap.task.runner;
|
||||
|
||||
|
||||
import com.bonus.emergencyrap.task.service.QuartzJobService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class JobInitializer implements CommandLineRunner {
|
||||
private static final Logger logger = LoggerFactory.getLogger(JobInitializer.class);
|
||||
|
||||
@Autowired
|
||||
private QuartzJobService quartzJobService;
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
try {
|
||||
// 启动定时任务
|
||||
quartzJobService.startSampleJob();
|
||||
} catch (Exception e) {
|
||||
logger.error("启动定时任务失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
package com.bonus.emergencyrap.task.service;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.bonus.emergencyrap.task.job.ActuatorJob;
|
||||
import com.bonus.emergencyrap.task.job.ScanJob;
|
||||
|
||||
import com.bonus.emergencyrap.vo.TaskVo;
|
||||
import org.quartz.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
||||
|
||||
@Service
|
||||
public class QuartzJobService {
|
||||
private static final Logger logger = LoggerFactory.getLogger(QuartzJobService.class);
|
||||
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
// 从配置文件读取简单间隔时间(秒)
|
||||
@Value("${task.interval.seconds}")
|
||||
private int taskIntervalSeconds;
|
||||
|
||||
public static String defeatGroup="EmergencyRap";
|
||||
|
||||
|
||||
|
||||
// 固定任务 用来扫描全部的定时任务
|
||||
public void startSampleJobWithSimpleTrigger() throws SchedulerException {
|
||||
// 定义任务
|
||||
JobDetail jobDetail = JobBuilder.newJob(ScanJob.class)
|
||||
.usingJobData("taskId","555555555555")
|
||||
.withIdentity("scanJob", "scanJobGroup")
|
||||
.withDescription("扫描器")
|
||||
.storeDurably()
|
||||
.build();
|
||||
|
||||
// 调度任务
|
||||
if (!scheduler.checkExists(jobDetail.getKey())) {
|
||||
// 从配置文件获取间隔时间,创建触发器
|
||||
Trigger trigger = TriggerBuilder.newTrigger()
|
||||
.withIdentity("scanJobTrigger", "scanJobGroup")
|
||||
.usingJobData("taskId","555555555555")
|
||||
.withDescription("扫描器")
|
||||
.startNow()
|
||||
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
|
||||
.withIntervalInSeconds(taskIntervalSeconds)
|
||||
.repeatForever())
|
||||
.build();
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
logger.info("已启动任务扫描,间隔时间: {}秒", taskIntervalSeconds);
|
||||
} else {
|
||||
logger.info("任务已存在,无需重复启动");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 使用cron表达式调度
|
||||
public void addTask(TaskVo vo) throws SchedulerException {
|
||||
// 定义任务
|
||||
JobDetail jobDetail = JobBuilder.newJob(ActuatorJob.class)
|
||||
.withIdentity(vo.getTaskId(), defeatGroup)
|
||||
.withDescription("Cron定时任务")
|
||||
.storeDurably()
|
||||
.build();
|
||||
// 调度任务
|
||||
if (!scheduler.checkExists(jobDetail.getKey())) {
|
||||
Trigger trigger = TriggerBuilder.newTrigger()
|
||||
.withIdentity(vo.getTaskId(), defeatGroup)
|
||||
.usingJobData("taskId",vo.getTaskId())
|
||||
.withDescription(vo.getCorn())
|
||||
.startNow()
|
||||
.withSchedule(CronScheduleBuilder.cronSchedule(vo.getCorn()))
|
||||
.build();
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
logger.info("已启动Cron任务,表达式: {}", vo.getCorn());
|
||||
} else {
|
||||
updateJobTime(vo);
|
||||
logger.info("Cron任务已存在,进行定时任务时间更新");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 启动示例任务
|
||||
public void startSampleJob() throws SchedulerException {
|
||||
// 可以根据需要选择启动哪种类型的任务
|
||||
startSampleJobWithSimpleTrigger();
|
||||
}
|
||||
|
||||
// 暂停任务
|
||||
public void pauseJob(String jobName, String jobGroup) throws SchedulerException {
|
||||
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
|
||||
if (scheduler.checkExists(jobKey)) {
|
||||
scheduler.pauseJob(jobKey);
|
||||
logger.info("已暂停任务: {}:{}", jobGroup, jobName);
|
||||
}
|
||||
}
|
||||
|
||||
// 恢复任务
|
||||
public void resumeJob(String jobName, String jobGroup) throws SchedulerException {
|
||||
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
|
||||
if (scheduler.checkExists(jobKey)) {
|
||||
scheduler.resumeJob(jobKey);
|
||||
logger.info("已恢复任务: {}:{}", jobGroup, jobName);
|
||||
}
|
||||
}
|
||||
|
||||
// 删除任务
|
||||
public void deleteJob(TaskVo vo) throws SchedulerException {
|
||||
JobKey jobKey = JobKey.jobKey(vo.getTaskId(), defeatGroup);
|
||||
if (scheduler.checkExists(jobKey)) {
|
||||
scheduler.deleteJob(jobKey);
|
||||
logger.info("已删除任务: {}:{}", defeatGroup, vo.getTaskId());
|
||||
}
|
||||
}
|
||||
|
||||
// 删除任务
|
||||
public void deleteJob(String jobName, String jobGroup) throws SchedulerException {
|
||||
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
|
||||
if (scheduler.checkExists(jobKey)) {
|
||||
scheduler.deleteJob(jobKey);
|
||||
logger.info("已删除任务: {}:{}", jobGroup, jobName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新当前正在运行的任务的cron时间
|
||||
* @param
|
||||
* @param
|
||||
*/
|
||||
private void updateJobTime(TaskVo vo) throws SchedulerException {
|
||||
// 获取当前触发器
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(vo.getTaskId(), defeatGroup);
|
||||
CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
|
||||
String oldTime = cronTrigger.getCronExpression();
|
||||
if (!oldTime.equalsIgnoreCase(vo.getCorn())) {
|
||||
logger.info("定时任务已更新old和新的定时任务: {}:{}:{}", vo.getTaskName(),oldTime,vo.getCorn() );
|
||||
Trigger trigger = TriggerBuilder.newTrigger()
|
||||
.withIdentity(vo.getTaskId(), defeatGroup)
|
||||
.usingJobData("taskId",vo.getTaskId())
|
||||
.withDescription(vo.getCorn())
|
||||
.startNow()
|
||||
.withSchedule(CronScheduleBuilder.cronSchedule(vo.getCorn()))
|
||||
.build();
|
||||
//重置对应的job
|
||||
scheduler.rescheduleJob(triggerKey, trigger);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 刷新简单任务的执行间隔
|
||||
public void refreshSimpleJob(String jobName, String jobGroup, int newIntervalSeconds) throws SchedulerException {
|
||||
JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
|
||||
if (!scheduler.checkExists(jobKey)) {
|
||||
throw new SchedulerException("任务不存在: " + jobGroup + ":" + jobName);
|
||||
}
|
||||
// 获取当前触发器
|
||||
TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);
|
||||
Trigger oldTrigger = scheduler.getTrigger(triggerKey);
|
||||
|
||||
// 创建新的触发器
|
||||
Trigger newTrigger = TriggerBuilder.newTrigger()
|
||||
.withIdentity(triggerKey)
|
||||
.forJob(jobKey)
|
||||
.startNow()
|
||||
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
|
||||
.withIntervalInSeconds(newIntervalSeconds)
|
||||
.repeatForever())
|
||||
.build();
|
||||
|
||||
// 替换触发器
|
||||
scheduler.rescheduleJob(triggerKey, newTrigger);
|
||||
logger.info("已刷新简单任务 [{}:{}] 的执行间隔为 {} 秒",
|
||||
jobGroup, jobName, newIntervalSeconds);
|
||||
}
|
||||
}
|
||||
|
|
@ -93,5 +93,15 @@ public class TaskVo {
|
|||
*/
|
||||
private String isLogin;
|
||||
|
||||
/**
|
||||
* 0 关闭 1 启用
|
||||
*/
|
||||
private String status;
|
||||
/**
|
||||
* 定时任务表达式
|
||||
*/
|
||||
private String corn;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ token:
|
|||
# 令牌有效期(默认30分钟)
|
||||
expireTime: 30
|
||||
|
||||
task:
|
||||
interval:
|
||||
seconds: 60
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue