Spring使用之:Quartz定时任务为什么会被阻塞
2015-04-02 14:10
316 查看
周日,公司CTO给我打电话说,监控系统的数据从下午1点就不更新了。我登录服务器排除了数据同步问题,查看日志也没有例外抛出,查询了前一天的 日志发现几个数据库表空间溢出例外。最后定位,Spring定时任务挂掉了。重启应用恢复正常。周一早上,同样的问题又发生了,6点开始定时任务又停了。 Spring定时任务为什么会被阻塞呢?
原因:
周一中午,我在进行接口状态监控测试时发现,接口状态查询任务尽然会执行半小时。问题找到了,由于我在接口状态查询任务中没有设置读超时、在接口 网络繁忙时,接口状态查询任务会占用很长的时间,Spring定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行。接口状 态查询任务每5分钟执行一次,假如每次都执行1小时的话,其他任务就会被阻塞。因为Quartz的线程都被接口状态查询任务占用了。其他任务只有等待。
解决方法:
1.将JobDetail的concurrent属性配置为false。不允许任务并发执行。
2.任务执行时间较长时,查找根本问题。
实验:
JobOne.java
Java代码
package test.job;
import java.util.Date;
public class JobOne {
public void execute(){
System.out.println("execute JobOne(" + new Date()+ ")" );
try {
Thread.sleep(1000000 );
}catch (InterruptedException ire) {
20000
}
}
}
[java] view
plaincopy
package test.job;
import java.util.Date;
public class JobOne {
public void execute(){
System.out.println("execute JobOne("+new Date()+")");
try {
Thread.sleep(1000000);
}catch(InterruptedException ire) {
}
}
}
JobTwo.java
Java代码
package test.job;
import java.util.Date;
public class JobTwo {
public void execute(){
System.out.println("execute JobTwo(" + new Date()+ ")" );
}
}
[java] view
plaincopy
package test.job;
import java.util.Date;
public class JobTwo {
public void execute(){
System.out.println("execute JobTwo("+new Date()+")");
}
}
配置文件
Xml代码
<? xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx ="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-
beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!--===== jobOne =====-->
<!-- job -->
< bean id = "jobOne" class = "test.job.JobOne" >
</ bean >
<!-- job detail -->
< bean id = "jobOneDetail" class ="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
< property name = "targetObject" ref = "jobOne" />
< property name = "targetMethod" value = "execute" />
< property name = "concurrent" value = "true" />
</ bean >
<!-- Trigger -->
< bean id = "jobOneSimpleTrigger" class ="org.springframework.scheduling.quartz.SimpleTriggerBean" >
< property name = "jobDetail" ref = "jobOneDetail" />
< property name = "startDelay" > < value > 0 </ value > </ property >
< property name = "repeatInterval" > < value > 1000 </ value > </ property >
</ bean >
<!--===== jobTwo =====-->
<!-- job -->
< bean id = "jobTwo" class = "test.job.JobTwo" >
</ bean >
<!-- job detail -->
< bean id = "jobTwoDetail" class ="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
< property name = "targetObject" ref = "jobTwo" />
< property name = "targetMethod" value = "execute" />
< property name = "concurrent" value = "true" />
</ bean >
<!-- Trigger -->
< bean id = "jobTwoSimpleTrigger" class ="org.springframework.scheduling.quartz.SimpleTriggerBean" >
< property name = "jobDetail" ref = "jobTwoDetail" />
< property name = "startDelay" > < value > 0 </ value > </ property >
< property name = "repeatInterval" > < value > 1000 </ value > </ property >
</ bean >
<!--===== Schedule =====-->
<!-- schedule -->
< bean class = "org.springframework.scheduling.quartz.SchedulerFactoryBean" >
< property name = "triggers" >
< list >
< ref local = "jobOneSimpleTrigger" />
< ref local = "jobTwoSimpleTrigger" />
</ list >
</ property >
</ bean >
</ beans >
[xml] view
plaincopy
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-
beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!--===== jobOne =====-->
<!-- job -->
<bean id="jobOne" class="test.job.JobOne" >
</bean>
<!-- job detail -->
<bean id="jobOneDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="jobOne"/>
<property name="targetMethod" value="execute"/>
<property name="concurrent" value="true" />
</bean>
<!-- Trigger -->
<bean id="jobOneSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="jobOneDetail" />
<property name="startDelay"><value>0</value></property>
<property name="repeatInterval"><value>1000</value></property>
</bean>
<!--===== jobTwo =====-->
<!-- job -->
<bean id="jobTwo" class="test.job.JobTwo" >
</bean>
<!-- job detail -->
<bean id="jobTwoDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="jobTwo"/>
<property name="targetMethod" value="execute"/>
<property name="concurrent" value="true" />
</bean>
<!-- Trigger -->
<bean id="jobTwoSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="jobTwoDetail" />
<property name="startDelay"><value>0</value></property>
<property name="repeatInterval"><value>1000</value></property>
</bean>
<!--===== Schedule =====-->
<!-- schedule -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="jobOneSimpleTrigger"/>
<ref local="jobTwoSimpleTrigger"/>
</list>
</property>
</bean>
</beans>
MAIN类:
Java代码
package test.job;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JobTest {
private ApplicationContext ac;
public JobTest(ApplicationContext ac) {
this .ac = ac;
}
/**
* @param args
*/
public static void main(String[] args) {
JobTest job = new JobTest( new ClassPathXmlApplicationContext("applicationContext.xml" ));
}
}
[java] view
plaincopy
package test.job;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JobTest {
private ApplicationContext ac;
public JobTest(ApplicationContext ac) {
this.ac = ac;
}
/**
* @param args
*/
public static void main(String[] args) {
JobTest job = new JobTest(new ClassPathXmlApplicationContext("applicationContext.xml"));
}
}
测试结果:
当jobOne的concurrent为true时:
execute JobOne(Thu Jan 24 13:40:22 CST 2008)
execute JobTwo(Thu Jan 24 13:40:22 CST 2008)
execute JobOne(Thu Jan 24 13:40:22 CST 2008)
execute JobTwo(Thu Jan 24 13:40:22 CST 2008)
execute JobOne(Thu Jan 24 13:40:23 CST 2008)
execute JobTwo(Thu Jan 24 13:40:23 CST 2008)
execute JobOne(Thu Jan 24 13:40:24 CST 2008)
execute JobTwo(Thu Jan 24 13:40:24 CST 2008)
execute JobOne(Thu Jan 24 13:40:25 CST 2008)
execute JobTwo(Thu Jan 24 13:40:25 CST 2008)
execute JobOne(Thu Jan 24 13:40:26 CST 2008)
execute JobTwo(Thu Jan 24 13:40:26 CST 2008)
execute JobOne(Thu Jan 24 13:40:27 CST 2008)
execute JobTwo(Thu Jan 24 13:40:27 CST 2008)
execute JobOne(Thu Jan 24 13:40:28 CST 2008)
execute JobTwo(Thu Jan 24 13:40:28 CST 2008)
execute JobOne(Thu Jan 24 13:40:29 CST 2008)
execute JobTwo(Thu Jan 24 13:40:29 CST 2008)
execute JobOne(Thu Jan 24 13:40:31 CST 2008)
(JobOne并发执行,到这里所有任务阻塞没有信息输出,可以看出默认有10个线程,都被JobOne占用)
当jobOne的concurrent为false时:
execute JobOne(Thu Jan 24 13:43:00 CST 2008)
execute JobTwo(Thu Jan 24 13:43:00 CST 2008)
execute JobTwo(Thu Jan 24 13:43:00 CST 2008)
execute JobTwo(Thu Jan 24 13:43:01 CST 2008)
execute JobTwo(Thu Jan 24 13:43:02 CST 2008)
execute JobTwo(Thu Jan 24 13:43:03 CST 2008)
execute JobTwo(Thu Jan 24 13:43:04 CST 2008)
execute JobTwo(Thu Jan 24 13:43:05 CST 2008)
execute JobTwo(Thu Jan 24 13:43:06 CST 2008)
execute JobTwo(Thu Jan 24 13:43:07 CST 2008)
execute JobTwo(Thu Jan 24 13:43:08 CST 2008)
execute JobTwo(Thu Jan 24 13:43:09 CST 2008)
(JobOne不并发执行,JobTwo不会被阻塞)
原因:
周一中午,我在进行接口状态监控测试时发现,接口状态查询任务尽然会执行半小时。问题找到了,由于我在接口状态查询任务中没有设置读超时、在接口 网络繁忙时,接口状态查询任务会占用很长的时间,Spring定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行。接口状 态查询任务每5分钟执行一次,假如每次都执行1小时的话,其他任务就会被阻塞。因为Quartz的线程都被接口状态查询任务占用了。其他任务只有等待。
解决方法:
1.将JobDetail的concurrent属性配置为false。不允许任务并发执行。
2.任务执行时间较长时,查找根本问题。
实验:
JobOne.java
Java代码
package test.job;
import java.util.Date;
public class JobOne {
public void execute(){
System.out.println("execute JobOne(" + new Date()+ ")" );
try {
Thread.sleep(1000000 );
}catch (InterruptedException ire) {
20000
}
}
}
[java] view
plaincopy
package test.job;
import java.util.Date;
public class JobOne {
public void execute(){
System.out.println("execute JobOne("+new Date()+")");
try {
Thread.sleep(1000000);
}catch(InterruptedException ire) {
}
}
}
JobTwo.java
Java代码
package test.job;
import java.util.Date;
public class JobTwo {
public void execute(){
System.out.println("execute JobTwo(" + new Date()+ ")" );
}
}
[java] view
plaincopy
package test.job;
import java.util.Date;
public class JobTwo {
public void execute(){
System.out.println("execute JobTwo("+new Date()+")");
}
}
配置文件
Xml代码
<? xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx ="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-
beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!--===== jobOne =====-->
<!-- job -->
< bean id = "jobOne" class = "test.job.JobOne" >
</ bean >
<!-- job detail -->
< bean id = "jobOneDetail" class ="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
< property name = "targetObject" ref = "jobOne" />
< property name = "targetMethod" value = "execute" />
< property name = "concurrent" value = "true" />
</ bean >
<!-- Trigger -->
< bean id = "jobOneSimpleTrigger" class ="org.springframework.scheduling.quartz.SimpleTriggerBean" >
< property name = "jobDetail" ref = "jobOneDetail" />
< property name = "startDelay" > < value > 0 </ value > </ property >
< property name = "repeatInterval" > < value > 1000 </ value > </ property >
</ bean >
<!--===== jobTwo =====-->
<!-- job -->
< bean id = "jobTwo" class = "test.job.JobTwo" >
</ bean >
<!-- job detail -->
< bean id = "jobTwoDetail" class ="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
< property name = "targetObject" ref = "jobTwo" />
< property name = "targetMethod" value = "execute" />
< property name = "concurrent" value = "true" />
</ bean >
<!-- Trigger -->
< bean id = "jobTwoSimpleTrigger" class ="org.springframework.scheduling.quartz.SimpleTriggerBean" >
< property name = "jobDetail" ref = "jobTwoDetail" />
< property name = "startDelay" > < value > 0 </ value > </ property >
< property name = "repeatInterval" > < value > 1000 </ value > </ property >
</ bean >
<!--===== Schedule =====-->
<!-- schedule -->
< bean class = "org.springframework.scheduling.quartz.SchedulerFactoryBean" >
< property name = "triggers" >
< list >
< ref local = "jobOneSimpleTrigger" />
< ref local = "jobTwoSimpleTrigger" />
</ list >
</ property >
</ bean >
</ beans >
[xml] view
plaincopy
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-
beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<!--===== jobOne =====-->
<!-- job -->
<bean id="jobOne" class="test.job.JobOne" >
</bean>
<!-- job detail -->
<bean id="jobOneDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="jobOne"/>
<property name="targetMethod" value="execute"/>
<property name="concurrent" value="true" />
</bean>
<!-- Trigger -->
<bean id="jobOneSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="jobOneDetail" />
<property name="startDelay"><value>0</value></property>
<property name="repeatInterval"><value>1000</value></property>
</bean>
<!--===== jobTwo =====-->
<!-- job -->
<bean id="jobTwo" class="test.job.JobTwo" >
</bean>
<!-- job detail -->
<bean id="jobTwoDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="jobTwo"/>
<property name="targetMethod" value="execute"/>
<property name="concurrent" value="true" />
</bean>
<!-- Trigger -->
<bean id="jobTwoSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="jobTwoDetail" />
<property name="startDelay"><value>0</value></property>
<property name="repeatInterval"><value>1000</value></property>
</bean>
<!--===== Schedule =====-->
<!-- schedule -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref local="jobOneSimpleTrigger"/>
<ref local="jobTwoSimpleTrigger"/>
</list>
</property>
</bean>
</beans>
MAIN类:
Java代码
package test.job;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JobTest {
private ApplicationContext ac;
public JobTest(ApplicationContext ac) {
this .ac = ac;
}
/**
* @param args
*/
public static void main(String[] args) {
JobTest job = new JobTest( new ClassPathXmlApplicationContext("applicationContext.xml" ));
}
}
[java] view
plaincopy
package test.job;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JobTest {
private ApplicationContext ac;
public JobTest(ApplicationContext ac) {
this.ac = ac;
}
/**
* @param args
*/
public static void main(String[] args) {
JobTest job = new JobTest(new ClassPathXmlApplicationContext("applicationContext.xml"));
}
}
测试结果:
当jobOne的concurrent为true时:
execute JobOne(Thu Jan 24 13:40:22 CST 2008)
execute JobTwo(Thu Jan 24 13:40:22 CST 2008)
execute JobOne(Thu Jan 24 13:40:22 CST 2008)
execute JobTwo(Thu Jan 24 13:40:22 CST 2008)
execute JobOne(Thu Jan 24 13:40:23 CST 2008)
execute JobTwo(Thu Jan 24 13:40:23 CST 2008)
execute JobOne(Thu Jan 24 13:40:24 CST 2008)
execute JobTwo(Thu Jan 24 13:40:24 CST 2008)
execute JobOne(Thu Jan 24 13:40:25 CST 2008)
execute JobTwo(Thu Jan 24 13:40:25 CST 2008)
execute JobOne(Thu Jan 24 13:40:26 CST 2008)
execute JobTwo(Thu Jan 24 13:40:26 CST 2008)
execute JobOne(Thu Jan 24 13:40:27 CST 2008)
execute JobTwo(Thu Jan 24 13:40:27 CST 2008)
execute JobOne(Thu Jan 24 13:40:28 CST 2008)
execute JobTwo(Thu Jan 24 13:40:28 CST 2008)
execute JobOne(Thu Jan 24 13:40:29 CST 2008)
execute JobTwo(Thu Jan 24 13:40:29 CST 2008)
execute JobOne(Thu Jan 24 13:40:31 CST 2008)
(JobOne并发执行,到这里所有任务阻塞没有信息输出,可以看出默认有10个线程,都被JobOne占用)
当jobOne的concurrent为false时:
execute JobOne(Thu Jan 24 13:43:00 CST 2008)
execute JobTwo(Thu Jan 24 13:43:00 CST 2008)
execute JobTwo(Thu Jan 24 13:43:00 CST 2008)
execute JobTwo(Thu Jan 24 13:43:01 CST 2008)
execute JobTwo(Thu Jan 24 13:43:02 CST 2008)
execute JobTwo(Thu Jan 24 13:43:03 CST 2008)
execute JobTwo(Thu Jan 24 13:43:04 CST 2008)
execute JobTwo(Thu Jan 24 13:43:05 CST 2008)
execute JobTwo(Thu Jan 24 13:43:06 CST 2008)
execute JobTwo(Thu Jan 24 13:43:07 CST 2008)
execute JobTwo(Thu Jan 24 13:43:08 CST 2008)
execute JobTwo(Thu Jan 24 13:43:09 CST 2008)
(JobOne不并发执行,JobTwo不会被阻塞)
相关文章推荐
- Spring使用之:Quartz定时任务为什么会被阻塞
- Spring使用之:Quartz定时任务为什么会被阻塞
- 使用spring 的Quartz 定时任务入门
- Spring与Quartz的结合使用 主要用于定时任务!!!
- 使用spring quartz实现定时任务
- Spring中使用quartz执行定时任务的两种方式
- 使用Spring(17)Spring中的定时调度(Scheduling)--传统方式创建Quartz任务
- quartz 框架定时任务,使用spring @Scheduled注解执行定时任务
- spring boot环境下使用quartz设置定时任务
- quartz 框架定时任务,使用spring @Scheduled注解执行定时任务
- spring里面使用quartz实现定时任务
- 如何使用spring 定时调度 【 Spring+Quartz实现定时任务 】
- Spring中使用quartz插件实现定时任务
- Spring中使用quartz执行定时任务的两种方式
- spring中使用quartz实现定时任务
- 使用spring quartz实现定时任务
- 使用spring+quartz配置多个定时任务
- 使用Spring提供Quartz来实现定时任务
- 使用Spring+Quartz的定时任务。
- Spring 动态管理定时任务(使用quartz) 只是管理启动时间 不能做启动和暂停