由于项目优化重构,想将定时任务从quartz单机模式变成集群或分布式的方式。于是,百度了一圈。。。。修修改改。。。用集群的方式部署定时任务,测试可以。。。

集群?分布式?什么区别?

  集群:同一个业务,部署在多个服务器上

  分布式:一个业务分拆多个子业务,部署在不同的服务器上

或者说

  集群:是指在多台不同的服务器中部署相同应用或服务模块,构成一个集群,通过负载均衡设备对外提供服务。

  分布式:是指在多台不同的服务器中部署不同的服务模块,通过远程调用协同工作,对外提供服务。

平时常用的quartz单机模式

缺点:

  1.单台server如果挂太多定时任务,负载太重,若一个应用部署在两台或多台server上,而定时任务只在一台运行,资源没有合理优化使用。(没有负载均衡)

  2.若运行定时任务的某台server挂了,那么定时任务就不能进行下去,会影响后期业务发展。(没有failover-失效转移策略)

  3.且不说server挂了,如果是运行某个定时任务的线程或相关的某进程非正常退出时(比如进程崩溃,机器断电等),在server恢复后,不会继续执行该task,也会影响业务。

优点:

  1.实现方便,快捷,能满足一般的定时任务需求。

  2.job信息默认存储在内存中,访问快,性能佳。

(Quartz提供两种基本作业存储类型。第一种类型叫做RAMJobStore,第二种类型叫做JDBC作业存储。)

主要原因是平时常用的quartz存储类型是RAMJobStore,在默认情况下Quartz将任务调度的运行信息保存在内存中,这种方法提供了最佳的性能,因为内存中数据访问最快。不足之处是缺乏数据的持久性,当程序路途停止或系统崩溃时,所有运行的信息都会丢失。

但是单机模式,如果自己写代码,把job是持久化到数据库中,应该也能实现上面的一些控制。

--------------------------------------我目前的quartz 集群 定时任务----------------------------------------------------

jdk版本:1.8.0_91

quartz版本:1.8.6  ---- 要到官网下载对应的表  quartz-1.8.6.tar\quartz-1.8.6\docs\dbTables\

spring版本:3.2.3

mysql版本:5.1.73

关于quartz的一些基本概念,就不说了,网上很多。quartz集群原理简单说下吧:

1.job要持久化到数据库,因为多台server部署了quartz,是通过同一个数据库的job信息进行感知job的执行情况,因此要有相关的 QRTZ_* 的表来存储这些信息,quartz官网中找

,比如我的quartz是1.8.6,则要去官网中找相应的版本的表,tables_mysql_innodb.sql (我的是mysql数据库,innodb数据库引擎 )。

2.多台server的quartz调度器都是尽最大努力去执行job,通过QRTZ_LOCKS 来锁定job,实现同步机制。(quartz1.8.6版本 QRTZ_LOCKS表 有5条记录:CALENDAR_ACCESS, JOB_ACCESS ,MISFIRE_ACCESS ,STATE_ACCESS ,TRIGGER_ACCESS)

关于行锁的机制:
1、mysql >  set autocommit=0;    //先把mysql设置为不自动提交。
2、 select * from es_locks where lock_name = 'TRIGGER_ACCESS' for update ;     //线程一通过for update 可以把这行锁住
3、 select * from es_locks where lock_name = 'TRIGGER_ACCESS' for update ;     //线程二通过for update 无法获得锁,线程等待。
4、commit;        //线程一通过commit 释放锁
5、 //线程二可以访问到数据,线程不再等待。
所以,通过这个机制,一次只能有一个线程来操作 加锁 -  操作 - 释放锁。  如果 操作 的时间过长的话,会带来集群间的主线程等待。
数据库行锁是一种悲观锁,锁表时其它线程无法查询。

原博文地址:http://blog.csdn.net/guolong1983811/article/details/51501366

quartz定时任务主要是三块东西:1.job  2.trigger  3.schedule    + quartz数据源的配置

直接上代码

1.applicationContext-quartz.xml中job的配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd"> <!-- 创建同步的话单 MethodInvokingJobDetailFactoryBean不支持序列化,所以用JobDetailBean -->
<bean id="createBbossCdrFileTimerJob" class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.cmcc.open.mssportal.util.MyDetailQuartzJobBean"></property>
<property name="jobDataAsMap">
<map>
<entry key="targetObject" value="createBbossCdrFileTask" /> <!-- 普通java类 CreateBbossCdrFileTask 记得要注入spring容器 -->
<entry key="targetMethod" value="createBbossCdrFile" /> <!-- 上面类中的定时任务方法 public void createBbossCdrFile() -->
</map>
</property>
<!-- 是否store,当没有trigger关联时 ,默认false -->
<!-- <property name="durability" value="true" /> -->
<!-- requestsRecovery属性设置为 true,当Quartz服务被中止后,再次启动或集群中其他机器接手任务时会尝试恢复执行之前未完成的所有任务。 -->
<!-- <property name="requestsRecovery" value="true" /> 若这个为true,则若job执行的进程中断或崩溃,不包括抛出异常,调度器检测到会重新开启执行该job
(与org.quartz.jobStore.misfireThreshold设置无关) -->

</bean> <!-- misfire处理策略
默认:MISFIRE_INSTRUCTION_SMART_POLICY=0
MISFIRE_INSTRUCTION_FIRE_ONCE_NOW=1
MISFIRE_INSTRUCTION_DO_NOTHING=2 -->

<bean id="createBbossCdrFileTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="createBbossCdrFileTimerJob"></property>
<property name="cronExpression" value="0/15 * * * * ?"></property>
<property name="misfireInstruction" value="2"></property>
</bean> <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="applicationContextSchedulerContextKey" value="applicationContext"></property>
<property name="configLocation" value="classpath:quartz.properties" />
<!-- 需要overwrite已经存在的job,如果需要动态的修改已经存在的job,就需要设置为true,否则会以数据库中已经存在的为准 -->
      <property name="overwriteExistingJobs" value="true" />   
<property name="triggers">
<list>
<ref bean="callRecordsTimerServiceTrigger"/>
</list>
</property>
</bean>
</beans>

其中 dataSource 我是配置在 applicationContext.xml中了
applicationContext.xml
 <!-- 数据库配置文件位置 -->
<context:property-placeholder location="classpath:datasource.properties" /> //配置在datasource.properties文件中,通过这个引入 <!-- 配置dbcp数据源 ,其中jdbc相关属性配置在了另外一个配置文件中,在这引用-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<!-- 队列中的最小等待数 -->
<property name="minIdle" value="${jdbc.minIdle}"></property>
<!-- 队列中的最大等待数 -->
<property name="maxIdle" value="${jdbc.maxIdle}"></property>
<!-- 最长等待时间,单位毫秒 -->
<property name="maxWait" value="${jdbc.maxWait}"></property>
<!-- 最大活跃数 -->
<property name="maxActive" value="${jdbc.maxActive}"></property>
<property name="initialSize" value="${jdbc.initialSize}"></property>
<property name="timeBetweenEvictionRunsMillis" value="86400"></property>
<property name="testWhileIdle" value="true"></property>
<property name="validationQuery" value="SELECT 1 FROM dual"></property>
</bean>


其中 com.cmcc.open.mssportal.util.MyDetailQuartzJobBean 
/*
* Project: zhejiang-refactor-open manager Webapp
*
* File Created at 2017年8月23日
*
* Copyright 2016 CMCC Corporation Limited.
* All rights reserved.
*
* This software is the confidential and proprietary information of
* ZYHY Company. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license.
*/
package com.cmcc.open.mssportal.util; import java.lang.reflect.Method; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.StatefulJob;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean; /**
* @Type MyDetailQuartzJobBean.java
* @Desc
* @author
* @date 2017年8月23日 上午10:22:38
* @version
*/
//实现StatefulJob接口,成为有状态的job,使Job不能并发执行 <==>相当于 常用的quartz配置 concurrent=false
public class MyDetailQuartzJobBean extends QuartzJobBean /* implements StatefulJob */ { protected final Log logger = LogFactory.getLog(getClass());
private String targetObject;
private String targetMethod;
private ApplicationContext ctx; @Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
try {
logger.info("execute [" + targetObject + "] at once>>>>>>");
Object otargetObject = ctx.getBean(targetObject);
Method m = null; try {
m = otargetObject.getClass().getMethod(targetMethod, new Class[] {});
m.invoke(otargetObject, new Object[] {});
} catch (SecurityException e) {
e.printStackTrace();
logger.error("-----MyDetailQuartzJobBean SecurityException" + e.getMessage(), e);
} catch (NoSuchMethodException e) {
e.printStackTrace();
logger.error("-----MyDetailQuartzJobBean NoSuchMethodException" + e.getMessage(),
e);
}
} catch (Exception e) {
throw new JobExecutionException(e);
}
} public void setApplicationContext(ApplicationContext applicationContext) {
this.ctx = applicationContext;
} public void setTargetObject(String targetObject) {
this.targetObject = targetObject;
} public void setTargetMethod(String targetMethod) {
this.targetMethod = targetMethod;
} }

2.quartz.properties 配置如下

#Configure Main Scheduler Properties
#调度标识名 集群中每一个实例都必须使用相同的名称
org.quartz.scheduler.instanceName = TestScheduler1
#ID设置为自动获取 每一个必须不同
org.quartz.scheduler.instanceId = AUTO #Configure ThreadPool
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
#自创建父线程
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
#org.quartz.plugin.shutdownhook.class = org.quartz.plugins.management.ShutdownHookPlugin
#org.quartz.plugin.shutdownhook.cleanShutdown = true
#Configure JobStore
#容许的最大作业延,若任务延迟时间超过该设定值,就被认为是misfire了,然后会执行关联的misfire策略(trigger中配置), 默认60s
org.quartz.jobStore.misfireThreshold = 1000

#数据保存方式为持久化
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.tablePrefix = QRTZ_
org.quartz.jobStore.maxMisfiresToHandleAtATime=10
#打开集群模式
org.quartz.jobStore.isClustered = true
#调度实例失效的检查时间间隔
org.quartz.jobStore.clusterCheckinInterval = 20000
spring配置就不说了,配置文件都要读进去,启动两台tomcat(修改另外一台tomcat的三个端口),不然启动会报错。

tomcat1            tomcat2
admin 8005     8085
http 8080        8088
ajp 8009         8089


测试现象
1.启动两台tomcat,两台都会执行不同的job。(同一个job只会在一台tomcat上执行)
2.关了其中一台,另外一台会执行所有的job。(上面配置文件applicationContext-quartz.xml中我只配置了一个job,测试的时候我配了多个job)
3.再启动刚刚关闭的那台tomcat,定时任务又会分配过来执行(很大概率会分配过来)。
4.若在某台tomcat在执行job时,把它强制关了(job没执行完),并且如果这个job设置了requestsRecovery=true,那么另外一台会检测到,然后重新执行该job。
最后谈谈 quartz.properties 中的 org.quartz.jobStore.misfireThreshold设置

理解成 “容许的最大作业延“,我觉得好理解,就是说,如果说某个定时任务的延迟时间,超过了该值,则会被认为是misfire(错过触发)了,紧着会执行相应的misfire策略,quartz1.8.6中有三种策略:
misfire处理策略
默认:MISFIRE_INSTRUCTION_SMART_POLICY=0 //默认的策略
MISFIRE_INSTRUCTION_FIRE_ONCE_NOW=1 //fire once now 马上触发一次
MISFIRE_INSTRUCTION_DO_NOTHING=2 //do nothing 不处理
日志分析
(下面的测试 都是MyDetailQuartzJobBean 没有实现 StatefulJob接口,换句话说,都是无状态的job,定时任务可以并发执行)

案例1
quartz1.8.6版本
每隔15秒 执行定时任务 定时任务要执行20s
设置misfirethreshold =2000ms 线程池:线程数量设置为1
默认的quartz misfire处理策略---MISFIRE_INSTRUCTION_SMART_POLICY

[scheduler_Worker-1] 2017-08-24 16:50:00 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 16:50:00 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 16:50:00
[QuartzScheduler_scheduler-huamao-HP1503564598330_MisfireHandler] 2017-08-24 16:50:18 INFO -org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:963) - Handling 1 trigger(s) that missed their scheduled fire-time.
[scheduler_Worker-1] 2017-08-24 16:50:20 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:96) - ---------createBbossCdrFile task end----------2017-08-24 16:50:20
[scheduler_Worker-1] 2017-08-24 16:50:20 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 16:50:20 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 16:50:20
[QuartzScheduler_scheduler-huamao-HP1503564598330_MisfireHandler] 2017-08-24 16:50:32 INFO -org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:963) - Handling 1 trigger(s) that missed their scheduled fire-time.
[QuartzScheduler_scheduler-huamao-HP1503564598330_MisfireHandler] 2017-08-24 16:50:36 INFO -org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:963) - Handling 1 trigger(s) that missed their scheduled fire-time.
[scheduler_Worker-1] 2017-08-24 16:50:40 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:96) - ---------createBbossCdrFile task end----------2017-08-24 16:50:40
[QuartzScheduler_scheduler-huamao-HP1503564598330_MisfireHandler] 2017-08-24 16:50:40 INFO -org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:963) - Handling 1 trigger(s) that missed their scheduled fire-time.
[scheduler_Worker-1] 2017-08-24 16:50:40 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 16:50:40 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 16:50:40
[QuartzScheduler_scheduler-huamao-HP1503564598330_MisfireHandler] 2017-08-24 16:50:48 INFO -org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:963) - Handling 1 trigger(s) that missed their scheduled fire-time.
[QuartzScheduler_scheduler-huamao-HP1503564598330_MisfireHandler] 2017-08-24 16:50:52 INFO -org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:963) - Handling 1 trigger(s) that missed their scheduled fire-time.

2017-08-24 16:50:00 -- 2017-08-24 16:50:20
2017-08-24 16:50:15 (这个定时任务 延迟了5s > 设定的misfirethreshold =2s, 被认为misfire了,所以该任务实际执行开始时间为2017-08-24 16:50:20 )

案例2
其他参数同案例1一样
设置misfirethreshold 2000000ms (设置大一点)
[scheduler_Worker-1] 2017-08-24 16:56:45 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 16:56:45 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 16:56:45
[scheduler_Worker-1] 2017-08-24 16:57:05 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:96) - ---------createBbossCdrFile task end----------2017-08-24 16:57:05
[scheduler_Worker-1] 2017-08-24 16:57:05 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 16:57:05 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 16:57:05
[scheduler_Worker-1] 2017-08-24 16:57:25 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:96) - ---------createBbossCdrFile task end----------2017-08-24 16:57:25
[scheduler_Worker-1] 2017-08-24 16:57:25 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 16:57:25 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 16:57:25
[scheduler_Worker-1] 2017-08-24 16:57:45 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:96) - ---------createBbossCdrFile task end----------2017-08-24 16:57:45
[scheduler_Worker-1] 2017-08-24 16:57:45 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 16:57:45 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 16:57:45
[scheduler_Worker-1] 2017-08-24 16:58:05 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:96) - ---------createBbossCdrFile task end----------2017-08-24 16:58:05
[scheduler_Worker-1] 2017-08-24 16:58:06 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 16:58:06 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 16:58:06
[scheduler_Worker-1] 2017-08-24 16:58:26 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:96) - ---------createBbossCdrFile task end----------2017-08-24 16:58:26

2017-08-24 16:56:45 -- 2017-08-24 16:57:05 实际 预期 2017-08-24 16:56:45 -- 2017-08-24 16:57:05 || 2017-08-24 16:57:00 -- 2017-08-24 16:57:20
2017-08-24 16:57:05 -- 2017-08-24 16:57:25

原来打算 开始
2017-08-24 16:56:45
2017-08-24 16:57:00
2017-08-24 16:57:15
但是只有一个线程,虽然没有misfire,但是好像是尽最大努力执行



案例3

其他同案例1不变 (产生misfire 用 MISFIRE_INSTRUCTION_DO_NOTHING 策略测试)
trigger的misfire 处理策略
<!-- <property name="misfireInstruction" value="2"></property> -->
<property name="misfireInstructionName" value="MISFIRE_INSTRUCTION_DO_NOTHING"></property>

[scheduler_Worker-1] 2017-08-24 17:32:45 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 17:32:45 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 17:32:45
[QuartzScheduler_scheduler-huamao-HP1503567162825_MisfireHandler] 2017-08-24 17:33:03 INFO -org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:963) - Handling 1 trigger(s) that missed their scheduled fire-time.
[scheduler_Worker-1] 2017-08-24 17:33:05 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:96) - ---------createBbossCdrFile task end----------2017-08-24 17:33:05
[scheduler_Worker-1] 2017-08-24 17:33:15 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 17:33:15 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 17:33:15
[QuartzScheduler_scheduler-huamao-HP1503567162825_MisfireHandler] 2017-08-24 17:33:33 INFO -org.quartz.impl.jdbcjobstore.JobStoreSupport.recoverMisfiredJobs(JobStoreSupport.java:963) - Handling 1 trigger(s) that missed their scheduled fire-time.
[scheduler_Worker-1] 2017-08-24 17:33:35 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:96) - ---------createBbossCdrFile task end----------2017-08-24 17:33:35
[scheduler_Worker-1] 2017-08-24 17:33:45 INFO -com.cmcc.open.mssportal.util.MyDetailQuartzJobBean.executeInternal(MyDetailQuartzJobBean.java:42) - execute [createBbossCdrFileTask] at once>>>>>>
[scheduler_Worker-1] 2017-08-24 17:33:45 INFO -com.cmcc.open.ss.timer.service.CreateBbossCdrFileTask.createBbossCdrFile(CreateBbossCdrFileTask.java:86) - ---------createBbossCdrFile task begin----------2017-08-24 17:33:45

预期执行 实际执行
2017-08-24 17:32:45 2017-08-24 17:32:45 -- 2017-08-24 17:33:05
2017-08-24 17:33:00 --> 这个错过啦 因为misfire策略设置donothing ,所以跳过该任务
2017-08-24 17:33:15 --> 开始执行这个
2017-08-24 17:33:30

刚好是按照cron时间表达式实行

案例4

如果 线程池:线程数量设置为10,那么会起来多个线程去执行该job

2017-08-24 17:32:45  线程1执行
2017-08-24 17:33:00   线程2执行
2017-08-24 17:33:15  线程3执行
2017-08-24 17:33:30 线程xxx执行  并不会misfire

案例5

设置:每隔15s执行 定时任务要执行20s(定时任务会超时)

为了防止任务并发,MyDetailQuartzJobBean 实现 StatefulJob接口,使之成为有状态的job

测试结果:

job只有一个线程去一个一个执行,不会并发。如果定时任务预期的执行时间 超时了,但是没有misfire,结果的执行策略是:尽最大努力执行的状态,一个执行完,马上执行下一个

如果超时了,并且超时时间大于org.quartz.jobStore.misfireThreshold的设置,即 misfire了,会执行相应的misfire策略。(若是donothing策略,则完全等价于 concurrent=false的设置)

我们平时常用的非集群,配置 concurrent=false,job不会并发,若是有个定时任务超时了,那就超时的这个任务就不会执行了,只会在按照cron时间表达式 继续执行下一个job。

原!总结 quartz集群 定时任务 测试运行ok的更多相关文章

  1. quartz集群 定时任务 改成可配置

    前面的博文中提到的quartz集群方式会有以下缺点: 1.假设配置了3个定时任务,job1,job2,job3,这时数据库里会有3条job相关的记录,如果下次上线要停掉一个定时任务job1,那即使定时 ...

  2. spring boot 整合 quartz 集群环境 实现 动态定时任务配置【原】

    最近做了一个spring boot 整合 quartz  实现 动态定时任务配置,在集群环境下运行的 任务.能够对定时任务,动态的进行增删改查,界面效果图如下: 1. 在项目中引入jar 2. 将需要 ...

  3. (4) Spring中定时任务Quartz集群配置学习

    原 来配置的Quartz是通过spring配置文件生效的,发现在非集群式的服务器上运行良好,但是将工程部署到水平集群服务器上去后改定时功能不能正常运 行,没有任何错误日志,于是从jar包.JDK版本. ...

  4. Spring+Quartz集群环境下定时调度的解决方案

    集群环境可能出现的问题 在上一篇博客我们介绍了如何在自己的项目中从无到有的添加了Quartz定时调度引擎,其实就是一个Quartz 和Spring的整合过程,很容易实现,但是我们现在企业中项目通常都是 ...

  5. 集群环境下定时调度的解决方案之Quartz集群

    集群环境可能出现的问题 在上一篇博客我们介绍了如何在自己的项目中从无到有的添加了Quartz定时调度引擎,其实就是一个Quartz 和Spring的整合过程,很容易实现,但是我们现在企业中项目通常都是 ...

  6. quartz集群报错but has failed to stop it. This is very likely to create a memory leak.

    quartz集群报错but has failed to stop it. This is very likely to create a memory leak. 在一台配置1核2G内存的阿里云服务器 ...

  7. Quartz集群

    为什么选择Quartz: 1)资历够老,创立于1998年,比struts1还早,但是一直在更新(27 April 2012: Quartz 2.1.5 Released),文档齐全. 2)完全由Jav ...

  8. quartz集群调度机制调研及源码分析---转载

    quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...

  9. 项目中使用Quartz集群分享--转载

    项目中使用Quartz集群分享--转载 在公司分享了Quartz,发布出来,希望大家讨论补充. CRM使用Quartz集群分享  一:CRM对定时任务的依赖与问题  二:什么是quartz,如何使用, ...

随机推荐

  1. Atitit.html解析器的选型 jsoup nsoup ,java c# .net 版本

    Atitit.html解析器的选型 jsoup nsoup ,java c# .net 版本 1. 框架选型的要求1 1.1. 文档多1 1.2. 跨平台1 2. html解析器特性:1 2.1. j ...

  2. Atitit.软件开发的最终的设计 dsl化,ast化(建立ast, 解析执行ast)

    Atitit.软件开发的最终的设计 dsl化,ast化(建立ast, 解析执行ast) 1. 使用js,html 撰写dsl1 1.1. 架构图1 1.2. html2 1.3. Js2 1.4. C ...

  3. JDBC深度封装的工具类 (具有高度可重用性)

    首先介绍一下Dbutils:    Common Dbutils是操作数据库的组件,对传统操作数据库的类进行二次封装,可以把结果集转化成List. 补充一下,传统操作数据库的类指的是JDBC(java ...

  4. 汉诺塔(-) java modPow 的用法;

    汉诺塔(一) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 在印度,有这么一个古老的传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针.印度教的 ...

  5. NPOI 导出Excel图片 (网络)

    导出网络图片,需要将网络图片下载到本地或者内存流中,建议下载的时候使用缩略图: 高清图片效率慢: Uri uri = new Uri(imgPath); //imgPath :网络图片地址 WebRe ...

  6. PHP学习笔记(13)班级和学生管理---班级

    两个文件夹,一个班级cls,一个学生stu. 两个表,一个班级cls,一个学生stu. 每个文件夹里有7个php文件:主界面cls.php-------增add.php,insert.php----- ...

  7. jQuery 实战读书笔记之第四章:使用特性、属性和数据

    使用属性 /* 每个元素都有一或多个特性,,这些特性的用途是给出相应元素或其内容的附加信息.(出自 JavaScript 高级程序设计) */ /* 特性是固有的 JavaScript 对象 属性指的 ...

  8. volatile关键字是什么意思

    我写了一段简单的对比代码并分别用vs2017以release方式编译然后用IDA观察汇编代码,如下图所示: 代码1 int a=5; printf("%d",a) 代码2 vola ...

  9. 【Mac + Python + Selenium】之PyCharm配置Selenium自动化

    一.安装PyCharm 1.下载地址: Pycharm编辑器官网下载地址 2.安装完成之后打开,一路下去点击,直到填写注册码,参考: <[转载][Pycharm编辑器破解步骤]之idea和Pyc ...

  10. JQ实现吸顶效果代码

    吸顶下过代码跟简单几行代码就可以了 如果滚动的军力大于100,就改变导航的定位方式,否则就默认 $(function(){         $(window).scroll(function(){   ...