整合 QuartJob ,实现定时器实时管理

  • 1、QuartJob简介
    • 1.1 核心API
  • 2、SpringBoot整合QuartJob
    • 2.1 项目结构
    • 2.2 定时器配置
    • 2.3 定时器管理工具
    • 2.4 定时器执行和日志
  • 3、定时器服务封装
    • 3.1 定时器初始化
    • 3.2 添加定时器
    • 3.3 立即执行一次定时器
    • 3.4 更新定时器
    • 3.5 停止定时器
    • 3.6 恢复定时器
    • 3.7 删除定时器
  • 4、配置一个测试的定时器
    • 4.1 定时接口封装
    • 4.2 测试定时器

1、QuartJob简介

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

1.1 核心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 名字、描述等。

2、SpringBoot整合QuartJob

2.1 项目结构

版本描述

spring-boot:2.1.3.RELEASE
quart-job:2.3.0

2.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 {@Beanpublic 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");// 集群配置:如果有多个调度器实体的话则必须设置为trueprop.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 启动时更新己存在的Jobfactory.setOverwriteExistingJobs(true);// 设置自动启动,默认为truefactory.setAutoStartup(true);return factory;}
}

2.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) ;}}
}

2.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) ;@Overrideprotected 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) ;}}
}

3、定时器服务封装

3.1 定时器初始化

@Service
public class ScheduleJobServiceImpl implements ScheduleJobService {@Resourceprivate Scheduler scheduler ;@Resourceprivate ScheduleJobMapper scheduleJobMapper ;/*** 定时器初始化*/@PostConstructpublic void init (){ScheduleJobExample example = new ScheduleJobExample() ;List<ScheduleJobBean> 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);}}}
}

3.2 添加定时器

@Override
@Transactional(rollbackFor = Exception.class)
public int insert(ScheduleJobBean record) {ScheduleUtil.createJob(scheduler,record);return scheduleJobMapper.insert(record);
}

3.3 立即执行一次定时器

@Override
@Transactional(rollbackFor = Exception.class)
public void run(Long jobId) {ScheduleJobBean scheduleJobBean = scheduleJobMapper.selectByPrimaryKey(jobId) ;ScheduleUtil.run(scheduler,scheduleJobBean);
}

3.4 更新定时器

@Override
@Transactional(rollbackFor = Exception.class)
public int updateByPrimaryKeySelective(ScheduleJobBean record) {ScheduleUtil.updateJob(scheduler,record);return scheduleJobMapper.updateByPrimaryKeySelective(record);
}

3.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) ;
}

3.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) ;
}

3.7 删除定时器

@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Long jobId) {ScheduleUtil.deleteJob(scheduler, jobId);scheduleJobMapper.deleteByPrimaryKey(jobId) ;
}

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

4.1 定时接口封装

public interface TaskService {void run(String params);
}

4.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") ;@Overridepublic void run(String params) {LOG.info("Params === >> " + params);LOG.info("当前时间::::"+format.format(new Date()));}
}

(六)整合 QuartJob ,实现定时器实时管理相关推荐

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

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

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

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

  3. Linux第六周学习总结——进程额管理和进程的创建

    Linux第六周学习总结--进程额管理和进程的创建 作者:刘浩晨 [原创作品转载请注明出处] <Linux内核分析>MOOC课程http://mooc.study.163.com/cour ...

  4. pic单片机内部时钟校准c语言,PIC系列单片机片内定时器实时时钟的实现(转)

    PIC系列单片机片内定时器实时时钟的实现(转) (2008-08-11 14:24:59) 标签: 杂谈 1. 1 振荡频率的考虑 工作频率为4MHz 的单片机, 选择32. 768kHz 的晶振显然 ...

  5. Shiro 整合SpringMVC 并实现权限管理,登录和注销

    Shiro 整合SpringMVC 并且实现权限管理,登录和注销 Apache Shiro是Java的一个安全框架.目前,使用Apache Shiro的人越来越多,因为它相当简单,对比Spring S ...

  6. 解决在Spring整合Hibernate配置tx事务管理器出现错误的问题

    解决在Spring整合Hibernate配置tx事务管理器出现错误的问题 参考文章: (1)解决在Spring整合Hibernate配置tx事务管理器出现错误的问题 (2)https://www.cn ...

  7. 群晖NAS教程(十六)、利用Docker安装GitLab管理代码工具

    为了更好的浏览体验,欢迎光顾勤奋的凯尔森同学个人博客 群晖NAS教程(十六).利用Docker安装GitLab管理代码工具 群晖DSM上安装GitLab有两种方式,一种是直接在群晖套件上安装,另一种是 ...

  8. linux 拍照的软件,六款优秀的Linux照片管理软件

    数字摄影技术让摄影师不用再担心照片处理问题,他们可以放心拍摄数千幅照片,唯一需要担心的是充电. 多数数字照相机是以RAW格式储存原始照片,这些照片未经过处理,用户一般需要利用计算机软件去进行处理,如转 ...

  9. 移动考勤满足企业实时管理

    依托中国移动的通讯网络技术,向企业提供基于互联网和手机应用的考勤服务,满足企业实时管理和分层管理的需求,并帮助多分支机构企业实现统一管理考勤的目的.移动考勤由无线指纹考勤机和基于互联网的考勤管理平台构 ...

最新文章

  1. 2020中国人工智能年度评选报名即将截止!4大类别7大奖项开放申请
  2. 疯抢当当图书 618 优惠码,花 120 买 300
  3. python列表中包含元祖_python列表与元祖
  4. python入门区块链技术_区块链入门教程
  5. 如何学习matlab 知乎,知乎日报
  6. Keil | 解决Keil与Source Insight4.0配合使用时,代码与注释位置(乱码)不一样的问题
  7. buck电路pscad仿真_100kVar SVG模块主电路选型分析[李博士]
  8. .sig 签名文件怎么使用
  9. 解决windows 下 mysql命令行导入备份文件 查询时乱码的问题
  10. 2022年了,如何制定今年的战略目标?人人必知
  11. 当当图书,这又是何苦。
  12. Yuga Labs「高处不胜寒」
  13. Java phantomjs 网页截图
  14. lsr: Cannot access .: No such file or directory. 解决办法
  15. 九龙证券|300亿空袭,港股吓懵了!
  16. js实现登录页面的背景图片的随机展示
  17. Nginx搭建RTMP推拉流服务器
  18. localhost解释
  19. 用joern画AST、CFG、CDG、DDG、PDG、CPG
  20. Opencv实现停车位识别

热门文章

  1. 2008.05.14 地震--灾难--捐款
  2. “商汤日日新”大模型体系全面升级,智能涌现,落地千行百业
  3. redis数据库数据类型(三)
  4. centos7的目录结构
  5. assembly.xml
  6. 六边形 蜂巢样式 svg方式 写法 初见
  7. Linux:centos:计划任务管理《at》
  8. 机器学习 之 Haar特征
  9. ue4 设置打包名称_[UE4]工程打包时添加自定义文件 - 纳金网
  10. 【与达梦同行】DM8适配JetBrains_Exposed框架