原!总结 quartz集群 定时任务 测试运行ok
由于项目优化重构,想将定时任务从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的更多相关文章
- quartz集群 定时任务 改成可配置
前面的博文中提到的quartz集群方式会有以下缺点: 1.假设配置了3个定时任务,job1,job2,job3,这时数据库里会有3条job相关的记录,如果下次上线要停掉一个定时任务job1,那即使定时 ...
- spring boot 整合 quartz 集群环境 实现 动态定时任务配置【原】
最近做了一个spring boot 整合 quartz 实现 动态定时任务配置,在集群环境下运行的 任务.能够对定时任务,动态的进行增删改查,界面效果图如下: 1. 在项目中引入jar 2. 将需要 ...
- (4) Spring中定时任务Quartz集群配置学习
原 来配置的Quartz是通过spring配置文件生效的,发现在非集群式的服务器上运行良好,但是将工程部署到水平集群服务器上去后改定时功能不能正常运 行,没有任何错误日志,于是从jar包.JDK版本. ...
- Spring+Quartz集群环境下定时调度的解决方案
集群环境可能出现的问题 在上一篇博客我们介绍了如何在自己的项目中从无到有的添加了Quartz定时调度引擎,其实就是一个Quartz 和Spring的整合过程,很容易实现,但是我们现在企业中项目通常都是 ...
- 集群环境下定时调度的解决方案之Quartz集群
集群环境可能出现的问题 在上一篇博客我们介绍了如何在自己的项目中从无到有的添加了Quartz定时调度引擎,其实就是一个Quartz 和Spring的整合过程,很容易实现,但是我们现在企业中项目通常都是 ...
- 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内存的阿里云服务器 ...
- Quartz集群
为什么选择Quartz: 1)资历够老,创立于1998年,比struts1还早,但是一直在更新(27 April 2012: Quartz 2.1.5 Released),文档齐全. 2)完全由Jav ...
- quartz集群调度机制调研及源码分析---转载
quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...
- 项目中使用Quartz集群分享--转载
项目中使用Quartz集群分享--转载 在公司分享了Quartz,发布出来,希望大家讨论补充. CRM使用Quartz集群分享 一:CRM对定时任务的依赖与问题 二:什么是quartz,如何使用, ...
随机推荐
- atitit.jndi的架构与原理以及资源配置and单元测试实践
atitit.jndi的架构与原理以及资源配置and单元测试实践 1. jndi架构 1 2. jndi实现原理 3 3. jndi资源配置 3 3.1. resin <database> ...
- Xilinx IP核使用(一)--FIFO
今天在将SRIO的数据存入FIFO后,然后把FIFO中的数据不断送入FFT进行运算时,对于几个控制信号总产生问题.所以单独对FIFO进行了仿真.原来感觉FIFO的几个参数端口一目了然啊,还需要什么深入 ...
- 【ZYNQ-7000开发之九】使用VDMA在PL和PS之间传输视频流数据
[ZYNQ-7000开发之九]使用VDMA在PL和PS之间传输视频流数据 原创 2016年01月14日 11:35:02 标签: VDMA / zynq / zedbaord / AXI 10384 ...
- python之圆周率
#!/usr/bin/env python #-*- coding:utf-8 -*- ############################ #File Name: pi.py #Author: ...
- 简单讲一下 SpringMVC的执行流程?
执行流程: 1. 用户向服务器发送请求,请求被 Spring 前端控制 Servelt DispatcherServlet 捕获(捕获) . DispatcherServlet对请求 URL进行解析 ...
- iOS swift 启动页加载广告(图片广告+视频广告)
一般app在启动的时候都会有广告页,广告页用来加载自己的或者第三方的广告,广告的展示形式也多种多样,最近在看swift相关的东西,这里将提供支持加载图片广告和视频广告的解决方案 思路: 我们知道在加载 ...
- 跟着百度学PHP[16]-验证码的学习
一个验证码需要有以下步骤: 验证底图 验证码内容 生成验证码 对比校验 验证码需要依靠PHP的GD扩展库.一些集成环境是默认安装了GD拓展库. <?php //创建一个100*30px图片,默认 ...
- MapReduce机制
1. MapReduce是一种分布式计算模型,由Google提出,主要用于搜索领域,解决海量数据的计算问题.2. MR由两个阶段组成:Map和Reduce,用户只需要实现map()和reduce()两 ...
- linux—jdk 安装步骤
1. 查看现有版本 java -version 2. 查看jdk的具体版本 rpm –qa| grep jdk rpm –qa| grep gcj 3. ...
- PHP实现懒加载
寻常php的加载是通过include(),require()等方法来加载外部文件,之后再通过实例调用方法或直接调用静态方法,而这样子写引入语句实在很麻烦,有的框架会将特定路径的文件全部引入,直接实例化 ...