From 184b40bdbf082b060c8a314087e180997f894381 Mon Sep 17 00:00:00 2001 From: wyl <959814898@qq.com> Date: Mon, 26 Feb 2024 22:58:30 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spring-boot/pom.xml | 1 + spring-boot/quartz/pom.xml | 84 ++++++ .../src/main/java/com/wyl/quartz/AnHusky.java | 17 ++ .../com/wyl/quartz/cong/ScheduleConfig.java | 72 +++++ .../java/com/wyl/quartz/job/ScheduleJob.java | 32 +++ .../com/wyl/quartz/web/JobController.java | 260 ++++++++++++++++++ .../quartz/src/main/resources/application.yml | 16 ++ .../src/main/resources/log4j.properties | 4 + .../src/main/resources/quartz.properties | 44 +++ 9 files changed, 530 insertions(+) create mode 100644 spring-boot/quartz/pom.xml create mode 100644 spring-boot/quartz/src/main/java/com/wyl/quartz/AnHusky.java create mode 100644 spring-boot/quartz/src/main/java/com/wyl/quartz/cong/ScheduleConfig.java create mode 100644 spring-boot/quartz/src/main/java/com/wyl/quartz/job/ScheduleJob.java create mode 100644 spring-boot/quartz/src/main/java/com/wyl/quartz/web/JobController.java create mode 100644 spring-boot/quartz/src/main/resources/application.yml create mode 100644 spring-boot/quartz/src/main/resources/log4j.properties create mode 100644 spring-boot/quartz/src/main/resources/quartz.properties diff --git a/spring-boot/pom.xml b/spring-boot/pom.xml index 30006b0..a493eda 100644 --- a/spring-boot/pom.xml +++ b/spring-boot/pom.xml @@ -15,6 +15,7 @@ spring-boot-rabbitmq spring-boot-mybatis spring-boot-wxrobot + quartz spring-boot diff --git a/spring-boot/quartz/pom.xml b/spring-boot/quartz/pom.xml new file mode 100644 index 0000000..9b9bb80 --- /dev/null +++ b/spring-boot/quartz/pom.xml @@ -0,0 +1,84 @@ + + + + spring-boot + com.wyl.example + 1.0-SNAPSHOT + ../pom.xml + + 4.0.0 + + quartz + + + 11 + 11 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + + + + + org.quartz-scheduler + quartz + + + org.quartz-scheduler + quartz-jobs + + + org.springframework + spring-context-support + + + + + + mysql + mysql-connector-java + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 1.3.2 + + + + + + com.alibaba + druid-spring-boot-starter + 1.1.10 + + + + c3p0 + c3p0 + 0.9.1.2 + + + + org.projectlombok + lombok + + + + + org.apache.commons + commons-lang3 + + + + \ No newline at end of file diff --git a/spring-boot/quartz/src/main/java/com/wyl/quartz/AnHusky.java b/spring-boot/quartz/src/main/java/com/wyl/quartz/AnHusky.java new file mode 100644 index 0000000..b0940c2 --- /dev/null +++ b/spring-boot/quartz/src/main/java/com/wyl/quartz/AnHusky.java @@ -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); + } +} \ No newline at end of file diff --git a/spring-boot/quartz/src/main/java/com/wyl/quartz/cong/ScheduleConfig.java b/spring-boot/quartz/src/main/java/com/wyl/quartz/cong/ScheduleConfig.java new file mode 100644 index 0000000..729992a --- /dev/null +++ b/spring-boot/quartz/src/main/java/com/wyl/quartz/cong/ScheduleConfig.java @@ -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(); + } + +} \ No newline at end of file diff --git a/spring-boot/quartz/src/main/java/com/wyl/quartz/job/ScheduleJob.java b/spring-boot/quartz/src/main/java/com/wyl/quartz/job/ScheduleJob.java new file mode 100644 index 0000000..d2101bc --- /dev/null +++ b/spring-boot/quartz/src/main/java/com/wyl/quartz/job/ScheduleJob.java @@ -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:"); + } + } +} \ No newline at end of file diff --git a/spring-boot/quartz/src/main/java/com/wyl/quartz/web/JobController.java b/spring-boot/quartz/src/main/java/com/wyl/quartz/web/JobController.java new file mode 100644 index 0000000..16ab151 --- /dev/null +++ b/spring-boot/quartz/src/main/java/com/wyl/quartz/web/JobController.java @@ -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 addJob(@RequestParam(value = "jobClassName") String jobClassName, + @RequestParam(value = "jobGroupName") String jobGroupName, + @RequestParam(value = "cronExpression") String cronExpression) { + Map 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 pauseJob(@RequestParam(value = "jobClassName") String jobClassName, + @RequestParam(value = "jobGroupName") String jobGroupName) { + Map returnData = new HashMap(); + 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 resumeJob(String jobClassName, + String jobGroupName) { + Map returnData = new HashMap(); + 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 rescheduleJob(String jobClassName, + String jobGroupName, + String cronExpression) { + Map returnData = new HashMap(); + 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) + //工作项1:job名以及所属组 + .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 removeJob(String jobClassName, + String jobGroupName) { + Map returnData = new HashMap(); + 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; + } +} \ No newline at end of file diff --git a/spring-boot/quartz/src/main/resources/application.yml b/spring-boot/quartz/src/main/resources/application.yml new file mode 100644 index 0000000..a6ab9b2 --- /dev/null +++ b/spring-boot/quartz/src/main/resources/application.yml @@ -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 + + diff --git a/spring-boot/quartz/src/main/resources/log4j.properties b/spring-boot/quartz/src/main/resources/log4j.properties new file mode 100644 index 0000000..854f203 --- /dev/null +++ b/spring-boot/quartz/src/main/resources/log4j.properties @@ -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 \ No newline at end of file diff --git a/spring-boot/quartz/src/main/resources/quartz.properties b/spring-boot/quartz/src/main/resources/quartz.properties new file mode 100644 index 0000000..53ad15b --- /dev/null +++ b/spring-boot/quartz/src/main/resources/quartz.properties @@ -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