IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Quartz定时器知识概括 -> 正文阅读

[Java知识库]Quartz定时器知识概括

Quartz简介

Quartz简介:

  • Quartz是OpenSymphony开源组织在Jobscheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。
  • Quartz用一个小Java库发布文件(.jar文件),这个库文件包含了所有Quartz核心功能。这些功能的主要接口(API)是Scheduler接口。它提供了简单的操作,例如:将任务纳入日程或者从日程中取消,开始/停止/暂停日程进度。

定时器种类:

  • Quartz 中五种类型的Trigger:SimpleTrigger,CronTirgger,DateIntervalTrigger,NthIncludedDayTrigger和Calendar类( org.quartz.Calendar)。
  • 最常用的:
    ①SimpleTrigger:用来触发只需执行一次或者在给定时间触发并且重复N次且每次执行延迟一定时间的任务。
    ②CronTrigger:按照日历触发,例如“每个周五”,每个月10日中午或者10:15分。

存储方式:

  • RAMJobStore和JDBCJobStore对比:
类型优点缺点
RAMJobStore不要外部数据库,配置容易,运行速度快因为调度程序信息是存储在被分配给JVM的内存里面,所以,当应用程序停止运行时,所有调度信息将被丢失。另外因为存储到JVM内存里面,所以可以存储多少个Job和Trigger将会受到限制
JDBCJobStore支持集群,因为所有的任务信息都会保存到数据库中,可以控制事物,还有就是如果应用服务器关闭或者重启,任务信息都不会丢失,并且可以恢复因服务器关闭或者重启而导致执行失败的任务运行速度的快慢取决与连接数据库的快慢

表关系和解释:

  • 表关系:
    在这里插入图片描述
  • 解释:
表名称说明
qrtz_blob_triggersTrigger作为Blob类型存储(用于Quartz用户用JDBC创建他们自己定制的Trigger类型,JobStore 并不知道如何存储实例的时候)
qrtz_calendars以Blob类型存储Quartz的Calendar日历信息, quartz可配置一个日历来指定一个时间范围
qrtz_cron_triggers存储Cron Trigger,包括Cron表达式和时区信息。
qrtz_fired_triggers存储与已触发的Trigger相关的状态信息,以及相联Job的执行信息
qrtz_job_details存储每一个已配置的Job的详细信息
qrtz_locks存储程序的非观锁的信息(假如使用了悲观锁)
qrtz_paused_trigger_graps存储已暂停的Trigger组的信息
qrtz_scheduler_state存储少量的有关 Scheduler的状态信息,和别的 Scheduler 实例(假如是用于一个集群中)
qrtz_simple_triggers存储简单的 Trigger,包括重复次数,间隔,以及已触的次数
qrtz_triggers存储已配置的 Trigger的信息

核心类和关系:

  • 核心类:
    QuartzSchedulerThread:负责执行向QuartzScheduler注册的触发Trigger的工作的线程。
    ThreadPool:Scheduler使用一个线程池作为任务运行的基础设施,任务通过共享线程池中的线程提供运行效率。
    QuartzSchedulerResources:包含创建QuartzScheduler实例所需的所有资源(JobStore,ThreadPool等)。
    SchedulerFactory :提供用于获取调度程序实例的客户端可用句柄的机制。
    JobStore: 通过类实现的接口,这些类要为org.quartz.core.QuartzScheduler的使用提供一个org.quartz.Job和org.quartz.Trigger存储机制。作业和触发器的存储应该以其名称和组的组合为唯一性。
    QuartzScheduler :这是Quartz的核心,它是org.quartz.Scheduler接口的间接实现,包含调度org.quartz.Jobs,注册org.quartz.JobListener实例等的方法。
    Scheduler :这是Quartz Scheduler的主要接口,代表一个独立运行容器。调度程序维护JobDetails和触发器的注册表。 一旦注册,调度程序负责执行作业,当他们的相关联的触发器触发(当他们的预定时间到达时)。
    Trigger :具有所有触发器通用属性的基本接口,描述了job执行的时间出发规则。 - 使用TriggerBuilder实例化实际触发器。
    JobDetail :传递给定作业实例的详细信息属性。 JobDetails将使用JobBuilder创建/定义。
    Job:要由表示要执行的“作业”的类实现的接口。只有一个方法 void execute(jobExecutionContext context)(jobExecutionContext 提供调度上下文各种信息,运行时数据保存在jobDataMap中)
    <1>Job有个子接口StatefulJob ,代表有状态任务。有状态任务不可并发,前次任务没有执行完,后面任务处于阻塞等到。
  • 关系:
    ①一个job可以被多个Trigger 绑定,但是一个Trigger只能绑定一个job!
    在这里插入图片描述

配置文件:

quartz.properties
//调度标识名 集群中每一个实例都必须使用相同的名称 (区分特定的调度器实例)
org.quartz.scheduler.instanceName:DefaultQuartzScheduler
//ID设置为自动获取 每一个必须不同 (所有调度器实例中是唯一的)
org.quartz.scheduler.instanceId :AUTO
//数据保存方式为持久化 
org.quartz.jobStore.class :org.quartz.impl.jdbcjobstore.JobStoreTX
//表的前缀 
org.quartz.jobStore.tablePrefix : QRTZ_
//设置为TRUE不会出现序列化非字符串类到 BLOB 时产生的类版本问题
//org.quartz.jobStore.useProperties : true
//加入集群 true 为集群 false不是集群
org.quartz.jobStore.isClustered : false
//调度实例失效的检查时间间隔 
org.quartz.jobStore.clusterCheckinInterval:20000 
//容许的最大作业延长时间 
org.quartz.jobStore.misfireThreshold :60000
//ThreadPool 实现的类名 
org.quartz.threadPool.class:org.quartz.simpl.SimpleThreadPool
//线程数量 
org.quartz.threadPool.threadCount : 10
//线程优先级 
org.quartz.threadPool.threadPriority : 5(threadPriority 属性的最大值是常量 java.lang.Thread.MAX_PRIORITY,等于10。最小值为常量 java.lang.Thread.MIN_PRIORITY,为1)
//自创建父线程
//org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true 
//数据库别名
org.quartz.jobStore.dataSource : qzDS
//设置数据源
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:123456
org.quartz.dataSource.qzDS.maxConnection:10

JDBC插入表顺序:

  • 主要的JDBC操作类,执行sql顺序。
Simple_trigger :插入顺序
qrtz_job_details --->  qrtz_triggers --->  qrtz_simple_triggers
qrtz_fired_triggers
Cron_Trigger:插入顺序
qrtz_job_details --->  qrtz_triggers --->  qrtz_cron_triggers
qrtz_fired_triggers

Quartz简单入门

Job:

public class MyJob implements Job{
	private static final Logger log = LoggerFactory.getLogger(MyJob.class);

	@Override
	public void execute(JobExecutionContext context)throws JobExecutionException {
		log.info("MyJob  is start ..................");
		
		log.info("Hello quzrtz  "+
				new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ").format(new Date()));
		
		log.info("MyJob  is end .....................");
	}
}

RAM方式:

public class RAMQuartz {

	private static Logger _log = LoggerFactory.getLogger(RAMQuartz.class);
	
	public static void main(String[] args) throws SchedulerException {
		//1.创建Scheduler的工厂
		SchedulerFactory sf = new StdSchedulerFactory();
		//2.从工厂中获取调度器实例
		Scheduler scheduler = sf.getScheduler();
		
		
		//3.创建JobDetail
		JobDetail jb = JobBuilder.newJob(MyJob.class)
				.withDescription("this is a ram job") //job的描述
				.withIdentity("ramJob", "ramGroup") //job 的name和group
				.build();
		
		//任务运行的时间,SimpleSchedle类型触发器有效
		long time=  System.currentTimeMillis() + 3*1000L; //3秒后启动任务
		Date statTime = new Date(time);
		
		//4.创建Trigger
			//使用SimpleScheduleBuilder或者CronScheduleBuilder
		Trigger t = TriggerBuilder.newTrigger()
					.withDescription("")
					.withIdentity("ramTrigger", "ramTriggerGroup")
					//.withSchedule(SimpleScheduleBuilder.simpleSchedule())
					.startAt(statTime)  //默认当前时间启动
					.withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")) //两秒执行一次
					.build();
		
		//5.注册任务和定时器
		scheduler.scheduleJob(jb, t);
		
		//6.启动 调度器
		scheduler.start();
		_log.info("启动时间 : " + new Date());
			
	}
}

JDBC方式:

public class QuartzJdbcTest {
	
	public static void main(String[] args) throws SchedulerException,
			ParseException {
		startSchedule();
		//resumeJob();
	}
	/**
	 * 开始一个simpleSchedule()调度
	 */
	public static void startSchedule() {
		try {
			// 1、创建一个JobDetail实例,指定Quartz
			JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
			// 任务执行类
					.withIdentity("job1_1", "jGroup1")
					// 任务名,任务组
					.build();
		
			
			//触发器类型
			SimpleScheduleBuilder builder = SimpleScheduleBuilder
					// 设置执行次数
				    .repeatSecondlyForTotalCount(5);
			
			//CronScheduleBuilder builder = CronScheduleBuilder.cronSchedule("0/2 * * * * ?");
			// 2、创建Trigger
			Trigger trigger = TriggerBuilder.newTrigger()
					.withIdentity("trigger1_1", "tGroup1").startNow()
					.withSchedule(builder)
					.build();
			
			// 3、创建Scheduler
			Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
			scheduler.start();
			// 4、调度执行
			scheduler.scheduleJob(jobDetail, trigger);
			try {
				Thread.sleep(60000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			//关闭调度器
			scheduler.shutdown();

		} catch (SchedulerException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 从数据库中找到已经存在的job,并重新开户调度
	 */
	public static void resumeJob() {
		try {

			SchedulerFactory schedulerFactory = new StdSchedulerFactory();
			Scheduler scheduler = schedulerFactory.getScheduler();
			JobKey jobKey = new JobKey("job1_1", "jGroup1");
			List<? extends Trigger> triggers = scheduler.getTriggersOfJob(jobKey);
			//SELECT TRIGGER_NAME, TRIGGER_GROUP FROM {0}TRIGGERS WHERE SCHED_NAME = {1} AND JOB_NAME = ? AND JOB_GROUP = ?
			// 重新恢复在jGroup1组中,名为job1_1的 job的触发器运行
			if(triggers.size() > 0){
				for (Trigger tg : triggers) {
					// 根据类型判断
					if ((tg instanceof CronTrigger) || (tg instanceof SimpleTrigger)) {
						// 恢复job运行
						scheduler.resumeJob(jobKey);
					}
				}
				scheduler.start();
			}
			
		} catch (Exception e) {
			e.printStackTrace();

		}
	}
}

Spring和Quartz集成

RAM存储方式的xml配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

	<!-- 
		Spring整合Quartz进行配置遵循下面的步骤:
		1:定义工作任务的Job
		2:定义触发器Trigger,并将触发器与工作任务绑定
		3:定义调度器,并将Trigger注册到Scheduler
	 -->
	<!-- 1:定义任务的bean ,这里使用JobDetailFactoryBean,也可以使用MethodInvokingJobDetailFactoryBean ,配置类似-->
	<bean name="hwJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
		<!-- 指定job的名称 -->
		<property name="name" value="hw_job"/>
		<!-- 指定job的分组 -->
		<property name="group" value="hw_group"/>
		<!-- 指定具体的job类 -->
		<property name="jobClass" value="com.dufy.spring.quartz.chapter01.job.HelloWorldJob"/>
		<!-- 必须设置为true,如果为false,当没有活动的触发器与之关联时会在调度器中会删除该任务  -->
		<property name="durability" value="true"/>
		<!-- 指定spring容器的key,如果不设定在job中的jobmap中是获取不到spring容器的 -->
		<property name="applicationContextJobDataKey" value="applicationContext"/>
	</bean>
	<!-- 2.1:定义触发器的bean,定义一个Simple的Trigger,一个触发器只能和一个任务进行绑定 -->
	<!-- <bean name="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
		指定Trigger的名称
		<property name="name" value="hw_trigger"/>
		指定Trigger的名称
		<property name="group" value="hw_trigger_group"/>
		指定Tirgger绑定的Job
		<property name="jobDetail" ref="hwJob"/>
		指定Trigger的延迟时间 1s后运行
		<property name="startDelay" value="1000"/>
		指定Trigger的重复间隔  5s
		<property name="repeatInterval" value="5000"/>
		指定Trigger的重复次数
		<property name="repeatCount" value="5"/>
	</bean> -->
	
	<!-- 2.2:定义触发器的bean,定义一个Cron的Trigger,一个触发器只能和一个任务进行绑定 -->
	<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
		<!-- 指定Trigger的名称 -->
		<property name="name" value="hw_trigger"/>
		<!-- 指定Trigger的名称 -->
		<property name="group" value="hw_trigger_group"/>
		<!-- 指定Tirgger绑定的Job -->
		<property name="jobDetail" ref="hwJob"/>
		<!-- 指定Cron 的表达式 ,当前是每隔1s运行一次 -->
		<property name="cronExpression" value="0/1 * * * * ?" />
	</bean>
	
	
	<!-- 3.定义调度器,并将Trigger注册到调度器中 -->
	<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
		<property name="triggers">
			<list>
				<!-- <ref bean="simpleTrigger"/> -->
				<ref bean="cronTrigger"/>
			</list>
		</property>
		<!-- <property name="autoStartup" value="true" /> -->
	</bean>
	
</beans>

JDBC存储方式的xml配置文件:

  • Spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">


	<!-- =========JDBC版=========== -->
	<!-- 
		持久化数据配置,需要添加quartz.properties
	 -->
	<bean name="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
        <property name="configLocation" value="classpath:quartz.properties"/>	
	</bean>
	
</beans>
  • quartz.properties:
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#

#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName: dufy_test
org.quartz.scheduler.instanceId = AUTO

org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 2
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true

org.quartz.jobStore.misfireThreshold: 60000
#============================================================================
# Configure JobStore
#============================================================================
 
#default config
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
#持久化配置
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:true

#============================================================================
#havent cluster spring
#============================================================================
org.quartz.jobStore.isClustered = false  

#数据库表前缀
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:qzDS

#============================================================================
# Configure Datasources
#============================================================================
#JDBC驱动
org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz_test
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:root
org.quartz.dataSource.qzDS.maxConnection:10

SSMM和Quartz集成

配置文件介绍:

  • 在ApplicationContext.xml中添加下面的配置:
    ①dataSource:配置了dataSource会读取spring配置的数据库,不会去加载quartz.properties配置的数据源。
    ②applicationContextSchedulerContextKey:配置这个可以获取spring容器中的context。
    ③加载quartz配置文件信息。
<bean name="quartzScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" >
   <property name="dataSource" ref ="dataSource" />       
   <property name="applicationContextSchedulerContextKey" value="applicationContextKey"/>
   <property name="configLocation" value="classpath:quartz.properties"/>			
</bean>
  • 添加quartz.properties配置文件:
# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#

#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName: quartzScheduler
org.quartz.scheduler.instanceId = AUTO

org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 2
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true

org.quartz.jobStore.misfireThreshold: 60000
#============================================================================
# Configure JobStore
#============================================================================
 
#default config
#org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
#持久化配置
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:true

#============================================================================
#havent cluster spring
#============================================================================
org.quartz.jobStore.isClustered = false  

#数据库表前缀
org.quartz.jobStore.tablePrefix:qrtz_
#org.quartz.jobStore.dataSource:qzDS

#============================================================================
# Configure Datasources
#============================================================================
#JDBC驱动  Sping去管理dataSource ,这里不在配置数据源信息
#org.quartz.dataSource.qzDS.driver:com.mysql.jdbc.Driver
#org.quartz.dataSource.qzDS.URL:jdbc:mysql://localhost:3306/quartz_test
#org.quartz.dataSource.qzDS.user:root
#org.quartz.dataSource.qzDS.password:root
#org.quartz.dataSource.qzDS.maxConnection:10

BAO和Service接口:

  • Dao主要是用户的一些操作:
public interface IUserDao {
    int deleteByPrimaryKey(Integer id);

    int insert(User record);

    int insertSelective(User record);

    User selectByPrimaryKey(Integer id);

    int updateByPrimaryKeySelective(User record);

    int updateByPrimaryKey(User record);
    
    User findUser(User user);
}
  • Service主要是对定时任务的一些操作:
package org.ssm.dufy.service;

public interface QuartzService {

	/**
	 * addJob(方法描述:添加一个定时任务) <br />
	 * (方法适用条件描述: – 可选)
	 * 
	 * @param jobName
	 *            作业名称
	 * @param jobGroupName
	 *            作业组名称
	 * @param triggerName
	 *            触发器名称
	 * @param triggerGroupName
	 *            触发器组名称
	 * @param cls
	 *            定时任务的class
	 * @param cron
	 *            时间表达式 void
	 * @exception
	 * @since 1.0.0
	 */
	public void addJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName, Class cls, String cron);

	/**
	 * 
	 * @param oldjobName 原job name
	 * @param oldjobGroup 原job group
	 * @param oldtriggerName 原 trigger name
	 * @param oldtriggerGroup 原 trigger group
	 * @param jobName
	 * @param jobGroup
	 * @param triggerName
	 * @param triggerGroup
	 * @param cron
	 */
	public boolean modifyJobTime(String oldjobName,String oldjobGroup, String oldtriggerName, String oldtriggerGroup, String jobName, String jobGroup,String triggerName, String triggerGroup, String cron);

	/**
	 * 修改触发器调度时间
	 * @param triggerName  触发器名称
	 * @param triggerGroupName  触发器组名称
	 * @param cron cron表达式
	 */
	public void modifyJobTime(String triggerName,
			String triggerGroupName, String cron);

	
	/**
	 * 暂停指定的任务
	 * @param jobName 任务名称
	 * @param jobGroupName 任务组名称 
	 * @return
	 */
	public void pauseJob(String jobName,String jobGroupName);
	
	/**
	 * 恢复指定的任务
	 * @param jobName 任务名称
	 * @param jobGroupName 任务组名称 
	 * @return
	 */
	public void resumeJob(String jobName,String jobGroupName);
	
	/**
	 * 删除指定组任务
	 * @param jobName 作业名称
	 * @param jobGroupName 作业组名称
	 * @param triggerName 触发器名称
	 * @param triggerGroupName 触发器组名称
	 */
	public void removeJob(String jobName, String jobGroupName,
			String triggerName, String triggerGroupName);

	
	/**
	 * 开始所有定时任务。启动调度器
	 */
	public void startSchedule();

	/**
	 * 关闭调度器
	 */
	public void shutdownSchedule();
}

Quartz集群

Quartz集群原理与架构:

  • 一个Quartz集群中的每个节点是一个独立的Quartz应用,它又管理着其他的节点。这就意味着你必须对每个节点分别启动或停止。Quartz集群中,独立的Quartz节点并不与另一其的节点或是管理节点通信,而是通过相同的数据库表来感知到另一Quartz应用的。
  • 集群通过故障切换和负载平衡的功能,能给调度器带来高可用性和伸缩性。目前集群只能工作在JDBC-JobStore(JobStore TX或者JobStoreCMT)方式下,从本质上来说,是使集群上的每一个节点通过共享同一个数据库来工作的( Quartz通过启动两个维护线程来维护数据库状态实现集群管理,一个是检测节点状态线程,一个是恢复任务线程 )。
    ①负载平衡是自动完成的,集群的每个节点会尽快触发任务。当一个触发器的触发时间到达时,第一个节点将会获得任务(通过锁定),成为执行任务的节点。
    ②故障切换的发生是在当一个节点正在执行一个或者多个任务失败的时候。当一个节点失败了,其他的节点会检测到并且标 识在失败节点上正在进行的数据库中的任务。任何被标记为可恢复(任务详细信息的"requests recovery"属性)的任务都会被其他的节点重新执行。没有标记可恢复的任务只会被释放出来,将会在下次相关触发器触发时执行。
    在这里插入图片描述
    注意事项:
  • 时间同步问题:
    ①Quartz实际并不关心你是在相同还是不同的机器上运行节点。当集群放置在不同的机器上时,称之为水平集群。节点跑在同一台机器上时,称之为垂直集群。对于垂直集群,存在着单点故障的问题。这对高可用性的应用来说是无法接受的,因为一旦机器崩溃了,所有的节点也就被终止了。对于水平集群,存在着时间同步问题。
    ②节点用时间戳来通知其他实例它自己的最后检入时间。假如节点的时钟被设置为将来的时间,那么运行中的Scheduler将再也意识不到那个结点已经宕掉了。另一方面,如果某个节点的时钟被设置为过去的时间,也许另一节点就会认定那个节点已宕掉并试图接过它的Job重运行。最简单的同步计算机时钟的方式是使用某一个Internet时间服务器(Internet Time Server ITS)。
  • 节点争抢Job问题:
    ①因为Quartz使用了一个随机的负载均衡算法, Job以随机的方式由不同的实例执行。Quartz官网上提到当前,还不存在一个方法来指派(钉住) 一个 Job 到集群中特定的节点。
  • 从集群获取Job列表问题:
    ①当前,如果不直接进到数据库查询的话,还没有一个简单的方式来得到集群中所有正在执行的Job列表。请求一个Scheduler实例,将只能得到在那个实例上正运行Job的列表。Quartz官网建议可以通过写一些访问数据库JDBC代码来从相应的表中获取全部的Job信息。

Quartz配置

quartz.properties:

#quartz集群配置  
#调度标识名 集群中每一个实例都必须使用相同的名称    
org.quartz.scheduler.instanceName=DefaultQuartzScheduler
#ID设置为自动获取 每一个必须不同  
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.makeSchedulerThreadDaemon=true
#线程池的实现类(一般使用SimpleThreadPool即可满足需求)  
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
#指定在线程池里面创建的线程是否是守护线程
org.quartz.threadPool.makeThreadsDaemons=true
#指定线程数,至少为1(无默认值)
org.quartz.threadPool.threadCount:20
#设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY 10,最小为Thread.MIN_PRIORITY 1,默认为5) 
org.quartz.threadPool.threadPriority:5
#数据保存方式为数据库持久化  
org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
#数据库代理类,一般org.quartz.impl.jdbcjobstore.StdJDBCDelegate可以满足大部分数据库  
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
#表的前缀,默认QRTZ_  
org.quartz.jobStore.tablePrefix=QRTZ_
#是否加入集群
org.quartz.jobStore.isClustered=true
# 信息保存时间 默认值60秒   
org.quartz.jobStore.misfireThreshold=25000

Quartz分布式

简介:

  • 方案一:单独设置任务调度服务
    ①任务调度服务部署在单结点,定时任务以Http请求的方式去向网关调用任务请求,网关将请求分发到集群中的某一个节点,某一个节点执行任务。
  • 方案二:使用Redis分布式锁实现
    ①每个定时任务都在Redis中设置一个Key-Value的分布式锁,Key为自定义的每个定时任务的名字(如task1:redis:lock),Value为服务器Ip,同时设置合适的过期时间(例如设置为5min),只有获取到锁的服务才能执行任务,其他服务则只能等待轮询。
    ②每个节点在执行时,都要进行以下操作:
    1.是否存在Key,若不存在,则设置Key-Value,Value为当前节点的IP
    2.若存在Key,则比较Value是否是当前Ip,若是则获取到了锁继续执行定时任务,若不是,则没有获取到锁就不往下执行并定时任务轮询 直到它抢到锁为止。
  • 方案三:开源分布式框架(推荐)
    ①使用XXL-JOB实现
    xxl-job是一个轻量级的分布式任务调度框架,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。
    <1>xxl-job的设计思想为:
    (1)将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”负责发起调度请求
    (2)将任务抽象成分散的JobHandler,交由执行器统一管理,执行器负责接收调度请求并执行对应的JobHandler中业务逻辑
    <2>因此,“调度”和“任务”可以互相解偶,提高系统整体的稳定性和扩展性。
    ②Elastic-Job:Elastic-job在2.x之后,出现了两个相互独立的产品线:Elastic-job-lite和Elastic-job-cloud
    <1>Elastic-job-lite:定位为轻量级无中心化的解决方案,使用jar包的形式提供分布式任务的协调服务,外部依赖仅依赖于zookeeper。

分布式任务调度原理:

Job与Tigger状态

简介:

  • jobkey相当于一把钥匙连接 所有从 schedule 中 获取 信息的钥匙,你会获得 当前 钥匙 下 的初始化信息
JobKey jobkey = new JobKey(name,group)
scheduler.getJobDetail(jobKey).getJobDataMap().get("当时创建的名称")
  • 获取 该条记录下次 着火事件的时间
Date date = scheduler.getTriggersOfJob(jobKey).get(0).getNextFireTime();
  • 获得 该job 的 调度状态,也可以使用 jobkey
 TriggerKey triggerKey = TriggerKey.triggerKey(jobKey.getName(), jobKey.getGroup());
 scheduler.getTriggerState(triggerKey);
  • 状态情况分为以下几类 可以直接拿去用。
private static String getTriggerStatesCN(String key) {
    Map<String, String> map = new LinkedHashMap<String, String>();
    map.put("BLOCKED", "阻塞");
    map.put("COMPLETE", "完成");
    map.put("ERROR", "出错");
    map.put("NONE", "不存在");
    map.put("NORMAL", "正常");
    map.put("PAUSED", "暂停");

    map.put("4", "阻塞");
    map.put("2", "完成");
    map.put("3", "出错");
    map.put("-1", "不存在");
    map.put("0", "正常");
    map.put("1", "暂停");
    /*  **STATE_BLOCKED 4 阻塞
STATE_COMPLETE 2 完成
STATE_ERROR 3 错误
STATE_NONE -1 不存在
STATE_NORMAL 0 正常
STATE_PAUSED 1 暂停***/
    return map.get(key);
}

在这里插入图片描述

Quartz总结

Quartz总结:

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-22 14:31:58  更:2021-09-22 14:34:43 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 15:36:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码