一、QuartJob简介

1、一句话描述

Quartz是一个完全由java编写的开源作业调度框架,形式简易,功能强大。

2、核心API

(1)、Scheduler

代表一个 Quartz 的独立运行容器,Scheduler 将 Trigger 绑定到特定 JobDetail, 这样当 Trigger 触发时, 对应的 Job 就会被调度。

(2)、Trigger

描述 Job 执行的时间触发规则。主要有 SimpleTrigger 和 CronTrigger 两个子类,通过一个 TriggerKey 唯一标识。

(3)、Job

定义一个任务,规定了任务是执行时的行为。JobExecutionContext 提供了调度器的上下文信息,Job 的数据可从 JobDataMap 中获取。

(4)、JobDetail

Quartz 在每次执行 Job 时,都重新创建一个 Job 实例,所以它不直接接受一个 Job 的实例,相反它接收一个 Job 实现类。描述 Job 的实现类及其它相关的静态信息,如 Job 名字、描述等。

二、与SpringBoot2.0 整合

1、项目结构

版本描述

spring-boot:2.1.3.RELEASE

quart-job:2.3.0

2、定时器配置

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import javax.sql.DataSource;

import java.util.Properties;

@Configuration

public class ScheduleConfig {

@Bean

public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {

// Quartz参数配置

Properties prop = new Properties();

// Schedule调度器的实体名字

prop.put("org.quartz.scheduler.instanceName", "HuskyScheduler");

// 设置为AUTO时使用,默认的实现org.quartz.scheduler.SimpleInstanceGenerator是基于主机名称和时间戳生成。

prop.put("org.quartz.scheduler.instanceId", "AUTO");

// 线程池配置

prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");

prop.put("org.quartz.threadPool.threadCount", "20");

prop.put("org.quartz.threadPool.threadPriority", "5");

// JobStore配置:Scheduler在运行时用来存储相关的信息

// JDBCJobStore和JobStoreTX都使用关系数据库来存储Schedule相关的信息。

// JobStoreTX在每次执行任务后都使用commit或者rollback来提交更改。

prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");

// 集群配置:如果有多个调度器实体的话则必须设置为true

prop.put("org.quartz.jobStore.isClustered", "true");

// 集群配置:检查集群下的其他调度器实体的时间间隔

prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");

// 设置一个频度(毫秒),用于实例报告给集群中的其他实例

prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");

// 触发器触发失败后再次触犯的时间间隔

prop.put("org.quartz.jobStore.misfireThreshold", "12000");

// 数据库表前缀

prop.put("org.quartz.jobStore.tablePrefix", "qrtz_");

// 从 LOCKS 表查询一行并对这行记录加锁的 SQL 语句

prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");

// 定时器工厂配置

SchedulerFactoryBean factory = new SchedulerFactoryBean();

factory.setDataSource(dataSource);

factory.setQuartzProperties(prop);

factory.setSchedulerName("HuskyScheduler");

factory.setStartupDelay(30);

factory.setApplicationContextSchedulerContextKey("applicationContextKey");

// 可选,QuartzScheduler 启动时更新己存在的Job

factory.setOverwriteExistingJobs(true);

// 设置自动启动,默认为true

factory.setAutoStartup(true);

return factory;

}

}

3、定时器管理工具

import com.quart.job.entity.ScheduleJobBean;

import org.quartz.*;

/**

* 定时器工具类

*/

public class ScheduleUtil {

private ScheduleUtil (){}

private static final String SCHEDULE_NAME = "HUSKY_" ;

/**

* 触发器 KEY

*/

public static TriggerKey getTriggerKey(Long jobId){

return TriggerKey.triggerKey(SCHEDULE_NAME+jobId) ;

}

/**

* 定时器 Key

*/

public static JobKey getJobKey (Long jobId){

return JobKey.jobKey(SCHEDULE_NAME+jobId) ;

}

/**

* 表达式触发器

*/

public static CronTrigger getCronTrigger (Scheduler scheduler,Long jobId){

try {

return (CronTrigger)scheduler.getTrigger(getTriggerKey(jobId)) ;

} catch (SchedulerException e){

throw new RuntimeException("getCronTrigger Fail",e) ;

}

}

/**

* 创建定时器

*/

public static void createJob (Scheduler scheduler, ScheduleJobBean scheduleJob){

try {

// 构建定时器

JobDetail jobDetail = JobBuilder.newJob(TaskJobLog.class).withIdentity(getJobKey(scheduleJob.getJobId())).build() ;

CronScheduleBuilder scheduleBuilder = CronScheduleBuilder

.cronSchedule(scheduleJob.getCronExpression())

.withMisfireHandlingInstructionDoNothing() ;

CronTrigger trigger = TriggerBuilder.newTrigger()

.withIdentity(getTriggerKey(scheduleJob.getJobId()))

.withSchedule(scheduleBuilder).build() ;

jobDetail.getJobDataMap().put(ScheduleJobBean.JOB_PARAM_KEY,scheduleJob);

scheduler.scheduleJob(jobDetail,trigger) ;

// 如果该定时器处于暂停状态

if (scheduleJob.getStatus() == 1){

pauseJob(scheduler,scheduleJob.getJobId()) ;

}

} catch (SchedulerException e){

throw new RuntimeException("createJob Fail",e) ;

}

}

/**

* 更新定时任务

*/

public static void updateJob(Scheduler scheduler, ScheduleJobBean scheduleJob) {

try {

// 构建定时器

TriggerKey triggerKey = getTriggerKey(scheduleJob.getJobId());

CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCronExpression())

.withMisfireHandlingInstructionDoNothing();

CronTrigger trigger = getCronTrigger(scheduler, scheduleJob.getJobId());

trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

trigger.getJobDataMap().put(ScheduleJobBean.JOB_PARAM_KEY, scheduleJob);

scheduler.rescheduleJob(triggerKey, trigger);

// 如果该定时器处于暂停状态

if(scheduleJob.getStatus() == 1){

pauseJob(scheduler, scheduleJob.getJobId());

}

} catch (SchedulerException e) {

throw new RuntimeException("updateJob Fail",e) ;

}

}

/**

* 停止定时器

*/

public static void pauseJob (Scheduler scheduler,Long jobId){

try {

scheduler.pauseJob(getJobKey(jobId));

} catch (SchedulerException e){

throw new RuntimeException("pauseJob Fail",e) ;

}

}

/**

* 恢复定时器

*/

public static void resumeJob (Scheduler scheduler,Long jobId){

try {

scheduler.resumeJob(getJobKey(jobId));

} catch (SchedulerException e){

throw new RuntimeException("resumeJob Fail",e) ;

}

}

/**

* 删除定时器

*/

public static void deleteJob (Scheduler scheduler,Long jobId){

try {

scheduler.deleteJob(getJobKey(jobId));

} catch (SchedulerException e){

throw new RuntimeException("deleteJob Fail",e) ;

}

}

/**

* 执行定时器

*/

public static void run (Scheduler scheduler, ScheduleJobBean scheduleJob){

try {

JobDataMap dataMap = new JobDataMap() ;

dataMap.put(ScheduleJobBean.JOB_PARAM_KEY,scheduleJob);

scheduler.triggerJob(getJobKey(scheduleJob.getJobId()),dataMap);

} catch (SchedulerException e){

throw new RuntimeException("run Fail",e) ;

}

}

}

4、定时器执行和日志

import com.quart.job.entity.ScheduleJobBean;

import com.quart.job.entity.ScheduleJobLogBean;

import com.quart.job.service.ScheduleJobLogService;

import org.quartz.JobExecutionContext;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.scheduling.quartz.QuartzJobBean;

import java.lang.reflect.Method;

import java.util.Date;

/**

* 定时器执行日志记录

*/

public class TaskJobLog extends QuartzJobBean {

private static final Logger LOG = LoggerFactory.getLogger(TaskJobLog.class) ;

@Override

protected void executeInternal(JobExecutionContext context) {

ScheduleJobBean jobBean = (ScheduleJobBean)context.getMergedJobDataMap().get(ScheduleJobBean.JOB_PARAM_KEY) ;

ScheduleJobLogService scheduleJobLogService = (ScheduleJobLogService)SpringContextUtil.getBean("scheduleJobLogService") ;

// 定时器日志记录

ScheduleJobLogBean logBean = new ScheduleJobLogBean () ;

logBean.setJobId(jobBean.getJobId());

logBean.setBeanName(jobBean.getBeanName());

logBean.setParams(jobBean.getParams());

logBean.setCreateTime(new Date());

long beginTime = System.currentTimeMillis() ;

try {

// 加载并执行定时器的 run 方法

Object target = SpringContextUtil.getBean(jobBean.getBeanName());

Method method = target.getClass().getDeclaredMethod("run", String.class);

method.invoke(target, jobBean.getParams());

long executeTime = System.currentTimeMillis() - beginTime;

logBean.setTimes((int)executeTime);

logBean.setStatus(0);

LOG.info("定时器 === >> "+jobBean.getJobId()+"执行成功,耗时 === >> " + executeTime);

} catch (Exception e){

// 异常信息

long executeTime = System.currentTimeMillis() - beginTime;

logBean.setTimes((int)executeTime);

logBean.setStatus(1);

logBean.setError(e.getMessage());

} finally {

scheduleJobLogService.insert(logBean) ;

}

}

}

三、定时器服务封装

1、定时器初始化

@Service

public class ScheduleJobServiceImpl implements ScheduleJobService {

@Resource

private Scheduler scheduler ;

@Resource

private ScheduleJobMapper scheduleJobMapper ;

/**

* 定时器初始化

*/

@PostConstruct

public void init (){

ScheduleJobExample example = new ScheduleJobExample() ;

List scheduleJobBeanList = scheduleJobMapper.selectByExample(example) ;

for (ScheduleJobBean scheduleJobBean : scheduleJobBeanList) {

CronTrigger cronTrigger = ScheduleUtil.getCronTrigger(scheduler,scheduleJobBean.getJobId()) ;

if (cronTrigger == null){

ScheduleUtil.createJob(scheduler,scheduleJobBean);

} else {

ScheduleUtil.updateJob(scheduler,scheduleJobBean);

}

}

}

}

2、添加定时器

@Override

@Transactional(rollbackFor = Exception.class)

public int insert(ScheduleJobBean record) {

ScheduleUtil.createJob(scheduler,record);

return scheduleJobMapper.insert(record);

}

3、立即执行一次定时器

@Override

@Transactional(rollbackFor = Exception.class)

public void run(Long jobId) {

ScheduleJobBean scheduleJobBean = scheduleJobMapper.selectByPrimaryKey(jobId) ;

ScheduleUtil.run(scheduler,scheduleJobBean);

}

4、更新定时器

@Override

@Transactional(rollbackFor = Exception.class)

public int updateByPrimaryKeySelective(ScheduleJobBean record) {

ScheduleUtil.updateJob(scheduler,record);

return scheduleJobMapper.updateByPrimaryKeySelective(record);

}

5、停止定时器

@Override

@Transactional(rollbackFor = Exception.class)

public void pauseJob(Long jobId) {

ScheduleJobBean scheduleJobBean = scheduleJobMapper.selectByPrimaryKey(jobId) ;

ScheduleUtil.pauseJob(scheduler,jobId);

scheduleJobBean.setStatus(1);

scheduleJobMapper.updateByPrimaryKeySelective(scheduleJobBean) ;

}

6、恢复定时器

@Override

@Transactional(rollbackFor = Exception.class)

public void resumeJob(Long jobId) {

ScheduleJobBean scheduleJobBean = scheduleJobMapper.selectByPrimaryKey(jobId) ;

ScheduleUtil.resumeJob(scheduler,jobId);

scheduleJobBean.setStatus(0);

scheduleJobMapper.updateByPrimaryKeySelective(scheduleJobBean) ;

}

7、删除定时器

@Override

@Transactional(rollbackFor = Exception.class)

public void delete(Long jobId) {

ScheduleUtil.deleteJob(scheduler, jobId);

scheduleJobMapper.deleteByPrimaryKey(jobId) ;

}

四、配置一个测试的定时器

1、定时接口封装

public interface TaskService {

void run(String params);

}

2、测试定时器

@Component("getTimeTask")

public class GetTimeTask implements TaskService {

private static final Logger LOG = LoggerFactory.getLogger(GetTimeTask.class.getName()) ;

private static final SimpleDateFormat format =

new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") ;

@Override

public void run(String params) {

LOG.info("Params === >> " + params);

LOG.info("当前时间::::"+format.format(new Date()));

}

}

五、源代码

GitHub:知了一笑

总结

以上所述是小编给大家介绍的Spring Boot 2 整合 QuartJob 实现定时器实时管理功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

java的定时器不能提供实时保证_Spring Boot 2 整合 QuartJob 实现定时器实时管理功能...相关推荐

  1. (六)整合 QuartJob ,实现定时器实时管理

    整合 QuartJob ,实现定时器实时管理 1.QuartJob简介 1.1 核心API 2.SpringBoot整合QuartJob 2.1 项目结构 2.2 定时器配置 2.3 定时器管理工具 ...

  2. SpringBoot2.0 整合 QuartJob ,实现定时器实时管理

    一.QuartJob简介 1.一句话描述 Quartz是一个完全由java编写的开源作业调度框架,形式简易,功能强大. 2.核心API (1).Scheduler 代表一个 Quartz 的独立运行容 ...

  3. swaggerconfig.java下载_Spring Boot:整合Swagger文档

    综合概述 spring-boot作为当前最为流行的Java web开发脚手架,越来越多的开发者选择用其来构建企业级的RESTFul API接口.这些接口不但会服务于传统的web端(b/s),也会服务于 ...

  4. java批量上传文件_Spring boot 实现单个或批量文件上传功能

    一:添加依赖: org.springframework.boot spring-boot-starter-thymeleaf javax.servlet jstl org.apache.tomcat. ...

  5. java 程序迁移后oracle 数字溢出_Spring Boot 应用迁移到 Java 11

    你的Spring Boot App需要迁移到Java 11 吗? 最近,我们开始将应用程序从Java 8迁移到Java 11;在此之前,Oracle宣布将从2019年初开始停止为Java 8提供商业支 ...

  6. java中限制多人登录的_Spring Boot + Spring Security 防止用户在多处同时登录(一个用户同时只能登录一次)及源码分析...

    网上很多文章的实现方法写得比较复杂 这里介绍一个简单的方法. 实现 @Configuration @EnableWebSecurity public class SecurityConfigurati ...

  7. springboot oauth2登录成功处理器_Spring Boot Security 整合 OAuth2 设计安全API接口服务...

    简介 OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版.本文重点讲解Spring Boot项目对OAuth2进行的实现,如果你对OAut ...

  8. 项目服务接口设计_Spring Boot Security 整合 OAuth2 设计安全API接口服务

    简介 OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版.本文重点讲解Spring Boot项目对OAuth2进行的实现,如果你对OAut ...

  9. java毕业设计 springboo疫情温度打卡健康评测系统 (3)系统后台管理功能

最新文章

  1. 用jsp实现右导航窗格_不想升级操作系统,可以用这三种方法阻止Windows10更新
  2. 使用TESSERACT来识别字符
  3. Bzoj3060 [Poi2012]Tour de Byteotia
  4. 没有日志,只有MDF文件如何恢复数据库(转)[
  5. 【BZOJ1623】 [Usaco2008 Open]Cow Cars 奶牛飞车 贪心
  6. rhino4.0安装教程
  7. android 绘制分割线,Android EditText在其drawable和它的文本之间绘制一个分隔线
  8. 如何把一个bin文件捆绑到一个可执行文件exe中?
  9. [转]WTL的windows mobile环境的配置(vs2008)[最终版,验证通过]
  10. Telerik for AJAX RadGrid控件
  11. 自然辩证法2018版_2018年自然辩证法概论已整理-资源下载蚂蚁文库
  12. jQuery 插件——免费版
  13. 基于Vue的数据埋点统计
  14. [附源码]java+ssm计算机毕业设计个人所得税服务系统0dol2(源码+程序+数据库+部署)
  15. [facebook-wda]搭建iOS App自动化环境
  16. 笔记本cpu温度多少算正常
  17. 档案管理学试题及答案
  18. IRSHELL 3.8/3.81安装使用教程
  19. 白话运维002:系统,父系统,子系统
  20. 龙兵名片标准版v1.99.26 智能名片 AI名片 名片系统

热门文章

  1. Silverlight,WPF动画终极攻略之会飞的小鸟篇
  2. 超详细 Vagrant 入门指南,建议收藏
  3. [原创]双硬盘四系统安装全功略
  4. ffmpeg 源代码简单分析 : avcodec_decode_video2()/avcodec_send_packet()/avcodec_receive_frame()
  5. BZOJ1739: [Usaco2005 mar]Space Elevator 太空电梯
  6. kubernetes学习:留言板(Guestbook)系统的搭建
  7. Kali Linux 2021.1 详细安装教程
  8. ElementaryOS安装及常用环境配置
  9. 冠泽医疗通过聆讯:上半年营收降8% 孟宪震女儿已移民加拿大
  10. Kotlin类成员初始化顺序