定时任务

This commit is contained in:
wyl
2024-02-26 22:58:30 +08:00
parent b6ec759ae5
commit 184b40bdbf
9 changed files with 530 additions and 0 deletions
+1
View File
@@ -15,6 +15,7 @@
<module>spring-boot-rabbitmq</module>
<module>spring-boot-mybatis</module>
<module>spring-boot-wxrobot</module>
<module>quartz</module>
</modules>
<artifactId>spring-boot</artifactId>
+84
View File
@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-boot</artifactId>
<groupId>com.wyl.example</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>quartz</artifactId>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<!-- quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- druid数据源驱动 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,17 @@
package com.wyl.quartz;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 描述:
*
* @author liupenghao
* @create 2018-09-28 上午9:11
**/
@SpringBootApplication
public class AnHusky {
public static void main(String[] args) {
SpringApplication.run(AnHusky.class, args);
}
}
@@ -0,0 +1,72 @@
package com.wyl.quartz.cong;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.Properties;
/**
* 定时任务配置
*
* @author Administrator
*/
@Configuration
public class ScheduleConfig {
@Bean
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setDataSource(dataSource);
// quartz参数
factory.setQuartzProperties(quartzProperties());
factory.setSchedulerName("MyScheduler");
// 延时启动
factory.setStartupDelay(1);
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
// 可选,QuartzScheduler
// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
factory.setOverwriteExistingJobs(true);
// 设置自动启动,默认为true
factory.setAutoStartup(true);
/*
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
cronTriggerFactoryBean.setJobDetail(
JobBuilder.newJob(ScheduleJob.class).build());
cronTriggerFactoryBean.setStartDelay(3000);
cronTriggerFactoryBean.setCronExpression("0/10 * * * * ?");
// 通过这个设置 在项目启动时启动
factory.setTriggers(cronTriggerFactoryBean.getObject());
*/
return factory;
}
/**
* 加载Quartz配置
*
* @return
* @throws IOException
*/
@Bean
public Properties quartzProperties() throws IOException {
//使用Spring的PropertiesFactoryBean对属性配置文件进行管理
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
//注意:quartz的配置文件从指定系统目录中获取,而不是从classpath中获取
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
//propertiesFactoryBean.setLocation(new FileSystemResource(propertiesPath));
//重要:保证其初始化
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
}
@@ -0,0 +1,32 @@
package com.wyl.quartz.job;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;
/**
* 定时任务
*
* @author MrBird
*/
public class ScheduleJob extends QuartzJobBean {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
protected void executeInternal(JobExecutionContext context) {
try {
// 执行任务
System.out.println("-------执行吃饭任务----------");
logger.info("吃饭中。。。。。。。");
Thread.sleep(2000);
logger.info("吃完饭了。。。。。。");
} catch (Exception e) {
logger.error("任务执行失败,任务ID");
}
}
}
@@ -0,0 +1,260 @@
package com.wyl.quartz.web;
import com.wyl.quartz.job.ScheduleJob;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.rmi.ServerException;
import java.util.HashMap;
import java.util.Map;
import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
/**
* 描述:
*
* @author liupenghao
**/
@RequestMapping(value = "/job")
@Controller
public class JobController {
@Autowired
private Scheduler scheduler;
@PostMapping
@ResponseBody
public Object test() throws SchedulerException {
scheduler.start();
// 定义job,绑定我们的定时任务
JobDetail job2 = newJob(ScheduleJob.class).build();
// 执行任务,用定义好的触发器 和 任务
scheduler.scheduleJob(job2, getTrigger1());
return "{status:OK}";
}
/**
* 触发器立即触发,然后每隔2秒 触发一次,22:55:00:
*/
private static Trigger getTrigger1() {
//定义一个任务触发器
return newTrigger()
.withIdentity("job15", "group15")
//定点触发
//.startAt(sdf.parse("2018-09-27 10:27:00"))
// 五秒钟后触发
.startAt(DateBuilder.futureDate(5, DateBuilder.IntervalUnit.SECOND))
.withSchedule(simpleSchedule()
.withIntervalInSeconds(2)
.repeatForever())
//.withRepeatCount(0))
.endAt(DateBuilder.dateOf(22, 55, 0))
.build();
}
/**
* 添加定时任务
*
* @param jobClassName
* @param jobGroupName
* @param cronExpression
* @return
*/
@PostMapping("/addJob")
@ResponseBody
public Map<String, String> addJob(@RequestParam(value = "jobClassName") String jobClassName,
@RequestParam(value = "jobGroupName") String jobGroupName,
@RequestParam(value = "cronExpression") String cronExpression) {
Map<String, String> returnData = new HashMap<>();
try {
JobDetail jobDetail = JobBuilder
.newJob(getClass(jobClassName).getClass())
.withIdentity("测试-1-jojobdetailbdetail")
.build();
//构建CronTrigger触发器
CronTrigger cronTrigger = TriggerBuilder
.newTrigger()
.withSchedule(cronSchedule(cronExpression)
.withMisfireHandlingInstructionDoNothing()
)
.withIdentity("测试-1-cronTrigger")
.build();
//注册调度任务
scheduler.scheduleJob(jobDetail, cronTrigger);
//启动任务
scheduler.start();
returnData.put("msg", "添加调度任务成功");
} catch (Exception e) {
returnData.put("msg", "添加调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* 暂停定时任务
*
* @param jobClassName
* @param jobGroupName
* @return
*/
@PutMapping(value = "/pauseJob")
@ResponseBody
public Map<String, String> pauseJob(@RequestParam(value = "jobClassName") String jobClassName,
@RequestParam(value = "jobGroupName") String jobGroupName) {
Map<String, String> returnData = new HashMap<String, String>();
try {
//JobKey定义了job的名称和组别
JobKey jobKey = JobKey.jobKey(jobClassName, jobGroupName);
//暂停任务
scheduler.pauseJob(jobKey);
returnData.put("msg", "暂停调度任务成功");
} catch (SchedulerException e) {
returnData.put("msg", "暂停调度任务异常:" + e.getMessage());
} catch (Exception e) {
returnData.put("msg", "暂停调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* 启动已经暂停的任务
*
* @param jobClassName
* @param jobGroupName
* @return
*/
@PutMapping(value = "/resumeJob")
@ResponseBody
public Map<String, String> resumeJob(String jobClassName,
String jobGroupName) {
Map<String, String> returnData = new HashMap<String, String>();
try {
//JobKey定义了job的名称和组别
JobKey jobKey = JobKey.jobKey(jobClassName, jobGroupName);
//继续任务
scheduler.resumeJob(jobKey);
returnData.put("msg", "继续调度任务成功");
} catch (SchedulerException e) {
returnData.put("msg", "继续调度任务异常:" + e.getMessage());
} catch (Exception e) {
returnData.put("msg", "继续调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* 更新定时任务:
* --传入的triggerKey有与之匹配的
* --旧触发器的触发时间没有完成
*
* @param jobClassName
* @param jobGroupName
* @param cronExpression
* @return
*/
@PutMapping(value = "/rescheduleJob")
@ResponseBody
public Map<String, String> rescheduleJob(String jobClassName,
String jobGroupName,
String cronExpression) {
Map<String, String> returnData = new HashMap<String, String>();
try {
//构建旧的TriggerKey
TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);
//通过cron表达式构建CronScheduleBuilder
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
//从调度容器中获取旧的CronTrigger
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
//更新CronTrigger
trigger = trigger.getTriggerBuilder()
.withIdentity(triggerKey)
//工作项1job名以及所属组
.withSchedule(scheduleBuilder)
//工作项2:指定调度参数
.build();//构建
//更新调度任务
scheduler.rescheduleJob(triggerKey, trigger);
returnData.put("msg", "更新调度任务成功");
} catch (Exception e) {
returnData.put("msg", "更新调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* @param jobClassName
* @param jobGroupName
* @return
*/
@DeleteMapping(value = "/removeJob")
@ResponseBody
public Map<String, String> removeJob(String jobClassName,
String jobGroupName) {
Map<String, String> returnData = new HashMap<String, String>();
try {
//获得调度容器
//Scheduler scheduler = getCurrentScheduler();
//TriggerKey定义了trigger的名称和组别
TriggerKey triggerKey = TriggerKey.triggerKey(jobClassName, jobGroupName);
//暂停触发器
scheduler.resumeTrigger(triggerKey);
//暂停触发器
scheduler.unscheduleJob(triggerKey);
//移除任务
scheduler.deleteJob(JobKey.jobKey(jobClassName, jobGroupName));
returnData.put("msg", "删除调度任务成功");
} catch (SchedulerException e) {
returnData.put("msg", "删除调度任务异常:" + e.getMessage());
} catch (Exception e) {
returnData.put("msg", "删除调度任务异常:" + e.getMessage());
}
return returnData;
}
/**
* 获得指定的类实例
*
* @param classname
* @return
* @throws ServerException
*/
private Job getClass(String classname) throws ServerException {
Job baseJob = null;
try {
//加载参数指定的类
Class<?> classTmp = Class.forName(classname);
//实例化
baseJob = (Job) classTmp.newInstance();
} catch (Exception e) {
System.out.println(classname + "......找不到相应的类");
}
return baseJob;
}
}
@@ -0,0 +1,16 @@
server:
port: 8080
tomcat:
uri-encoding: utf-8
spring:
datasource:
druid:
# 数据库访问配置, 使用druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.123.102:3306/test?useUnicode=true&characterEncoding=utf8
username: root
password: Wyl.0629
name: anhusky
@@ -0,0 +1,4 @@
log4j.rootLogger=info, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
@@ -0,0 +1,44 @@
#============================================================================
# 基础配置
#============================================================================
# 设置调度器的实例名(instanceName) 和实例ID (instanceId)
org.quartz.scheduler.instanceName: MyScheduler
#如果使用集群,instanceId必须唯一,设置成AUTO
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# 调度器线程池配置
#============================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
# 指定多少个工作者线程被创建用来处理 Job
org.quartz.threadPool.threadCount: 20
# 设置工作者线程的优先级(最大值10,最小值1,常用值5)
org.quartz.threadPool.threadPriority: 5
#============================================================================
# Configure JobStore 作业存储配置
#============================================================================
# 持久化配置(存储方式使用JobStoreTX,也就是数据库)
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
#数据库中quartz表的表名前缀
org.quartz.jobStore.tablePrefix:t_qrtz_
org.quartz.jobStore.misfireThreshold: 5000
#是否使用集群(如果项目只部署到 一台服务器,就不用了)
org.quartz.jobStore.isClustered = false
#============================================================================
# Configure Datasources配置数据源(可被覆盖,如果在schedulerFactoryBean指定数据源)
#============================================================================
#org.quartz.jobStore.dataSource:anhusky
#
#org.quartz.dataSource.myQuartzDB.driver:com.mysql.jdbc.Driver
#org.quartz.dataSource.myQuartzDB.URL:jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
#org.quartz.dataSource.myQuartzDB.user:root
#org.quartz.dataSource.myQuartzDB.password:root123
#org.quartz.dataSource.myQuartzDB.maxConnections:10