Spring使用之:Quartz定时任务为什么会被阻塞

Spring使用之:Quartz定时任务为什么会被阻塞

文章分类:Java编程 关键字: spring, quartz, 定时任务 问题:

周日,公司CTO给我打电话说,监控系统的数据从下午1点就不更新了。我登录服务器排除了数据同步问题,查看日志也没有例外抛出,查询了前一天的 日志发现几个数据库表空间溢出例外。最后定位,Spring定时任务挂掉了。重启应用恢复正常。周一早上,同样的问题又发生了,6点开始定时任务又停了。 Spring定时任务为什么会被阻塞呢?

原因:

周一中午,我在进行接口状态监控测试时发现,接口状态查询任务尽然会执行半小时。问题找到了,由于我在接口状态查询任务中没有设置读超时、在接口 网络繁忙时,接口状态查询任务会占用很长的时间,Spring定时任务默认都是并发执行的,不会等待上一次任务执行完毕,只要间隔时间到就会执行。接口状 态查询任务每5分钟执行一次,假如每次都执行1小时的话,其他任务就会被阻塞。因为Quartz的线程都被接口状态查询任务占用了。其他任务只有等待。

解决方法:

1.将JobDetail的concurrent属性配置为false。不允许任务并发执行。
2.任务执行时间较长时,查找根本问题。

实验:

JobOne.java

Java代码
  1. package test.job;
  2. import java.util.Date;
  3. public class JobOne{
  4. public void execute(){
  5. System.out.println("executeJobOne(" + new Date()+ ")" );
  6. try {
  7. Thread.sleep(1000000 );
  8. }catch (InterruptedExceptionire){
  9. }
  10. }
  11. }
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代码
  1. package test.job;
  2. import java.util.Date;
  3. public class JobTwo{
  4. public void execute(){
  5. System.out.println("executeJobTwo(" + new Date()+ ")" );
  6. }
  7. }
package test.job;

import java.util.Date;

public class JobTwo {
	public void execute(){
		System.out.println("execute JobTwo("+new Date()+")");
	}

}



配置文件

Xml代码
  1. <? xml version = "1.0" encoding = "UTF-8" ?>
  2. < beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:aop = "http://www.springframework.org/schema/aop" xmlns:tx = "http://www.springframework.org/schema/tx"
  4. xsi:schemaLocation ="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-
  5. beans-2.0.xsd
  6. http://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd
  7. http://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
  8. <!--=====jobOne=====-->
  9. <!--job-->
  10. < bean id = "jobOne" class = "test.job.JobOne" >
  11. </ bean >
  12. <!--jobdetail-->
  13. < bean id = "jobOneDetail" class = "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
  14. < property name = "targetObject" ref = "jobOne" />
  15. < property name = "targetMethod" value = "execute" />
  16. < property name = "concurrent" value = "true" />
  17. </ bean >
  18. <!--Trigger-->
  19. < bean id = "jobOneSimpleTrigger" class = "org.springframework.scheduling.quartz.SimpleTriggerBean" >
  20. < property name = "jobDetail" ref = "jobOneDetail" />
  21. < property name = "startDelay" > < value > 0 </ value > </ property >
  22. < property name = "repeatInterval" > < value > 1000 </ value > </ property >
  23. </ bean >
  24. <!--=====jobTwo=====-->
  25. <!--job-->
  26. < bean id = "jobTwo" class = "test.job.JobTwo" >
  27. </ bean >
  28. <!--jobdetail-->
  29. < bean id = "jobTwoDetail" class = "org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >
  30. < property name = "targetObject" ref = "jobTwo" />
  31. < property name = "targetMethod" value = "execute" />
  32. < property name = "concurrent" value = "true" />
  33. </ bean >
  34. <!--Trigger-->
  35. < bean id = "jobTwoSimpleTrigger" class = "org.springframework.scheduling.quartz.SimpleTriggerBean" >
  36. < property name = "jobDetail" ref = "jobTwoDetail" />
  37. < property name = "startDelay" > < value > 0 </ value > </ property >
  38. < property name = "repeatInterval" > < value > 1000 </ value > </ property >
  39. </ bean >
  40. <!--=====Schedule=====-->
  41. <!--schedule-->
  42. < bean class = "org.springframework.scheduling.quartz.SchedulerFactoryBean" >
  43. < property name = "triggers" >
  44. < list >
  45. < ref local = "jobOneSimpleTrigger" />
  46. < ref local = "jobTwoSimpleTrigger" />
  47. </ list >
  48. </ property >
  49. </ bean >
  50. </ beans >
<?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代码
  1. package test.job;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.support.ClassPathXmlApplicationContext;
  4. public class JobTest{
  5. private ApplicationContextac;
  6. public JobTest(ApplicationContextac){
  7. this .ac=ac;
  8. }
  9. /**
  10. *@paramargs
  11. */
  12. public static void main(String[]args){
  13. JobTestjob=new JobTest( new ClassPathXmlApplicationContext( "applicationContext.xml" ));
  14. }
  15. }
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不会被阻塞)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值