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

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

原因: 

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

解决方法: 

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

实验: 

JobOne.java

Java代码
  1. package  test.job;  
  2.   
  3. import  java.util.Date;  
  4.   
  5. public   class  JobOne {  
  6.     public   void  execute(){  
  7.         System.out.println("execute JobOne(" + new  Date()+ ")" );  
  8.         try  {  
  9.             Thread.sleep(1000000 );  
  10.         }catch (InterruptedException ire) {  
  11.               
  12.         }  
  13.     }  
  14. }  
[java]  view plain copy
  1. package test.job;  
  2.   
  3. import java.util.Date;  
  4.   
  5. public class JobOne {  
  6.     public void execute(){  
  7.         System.out.println("execute JobOne("+new Date()+")");  
  8.         try {  
  9.             Thread.sleep(1000000);  
  10.         }catch(InterruptedException ire) {  
  11.               
  12.         }  
  13.     }  
  14. }  


JobTwo.java

Java代码
  1. package  test.job;  
  2.   
  3. import  java.util.Date;  
  4.   
  5. public   class  JobTwo {  
  6.     public   void  execute(){  
  7.         System.out.println("execute JobTwo(" + new  Date()+ ")" );  
  8.     }  
  9.   
  10. }  
[java]  view plain copy
  1. package test.job;  
  2.   
  3. import java.util.Date;  
  4.   
  5. public class JobTwo {  
  6.     public void execute(){  
  7.         System.out.println("execute JobTwo("+new Date()+")");  
  8.     }  
  9.   
  10. }  



配置文件

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/beans http://www.springframework.org/schema/beans/spring-  
  5.   
  6. beans-2.0.xsd  
  7.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd  
  8.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">   
  9.   
  10.        
  11.       
  12.        
  13.       
  14.     < bean   id = "jobOne"   class = "test.job.JobOne"   >   
  15.           
  16.      bean >   
  17.       
  18.        
  19.       
  20.     < bean   id = "jobOneDetail"   class ="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >   
  21.         < property   name = "targetObject"   ref = "jobOne" />   
  22.         < property   name = "targetMethod"   value = "execute" />   
  23.         < property   name = "concurrent"   value = "true"   />   
  24.      bean >   
  25.       
  26.        
  27.       
  28.     < bean   id = "jobOneSimpleTrigger"   class ="org.springframework.scheduling.quartz.SimpleTriggerBean" >   
  29.         < property   name = "jobDetail"   ref = "jobOneDetail"   />   
  30.         < property   name = "startDelay" > < value > 0  value >  property >   
  31.         < property   name = "repeatInterval" > < value > 1000  value >  property >   
  32.      bean >   
  33.       
  34.        
  35.       
  36.        
  37.       
  38.     < bean   id = "jobTwo"   class = "test.job.JobTwo"   >   
  39.           
  40.      bean >   
  41.       
  42.        
  43.       
  44.     < bean   id = "jobTwoDetail"   class ="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean" >   
  45.         < property   name = "targetObject"   ref = "jobTwo" />   
  46.         < property   name = "targetMethod"   value = "execute" />   
  47.         < property   name = "concurrent"   value = "true"   />   
  48.      bean >   
  49.       
  50.        
  51.       
  52.     < bean   id = "jobTwoSimpleTrigger"   class ="org.springframework.scheduling.quartz.SimpleTriggerBean" >   
  53.         < property   name = "jobDetail"   ref = "jobTwoDetail"   />   
  54.         < property   name = "startDelay" > < value > 0  value >  property >   
  55.         < property   name = "repeatInterval" > < value > 1000  value >  property >   
  56.      bean >   
  57.       
  58.       
  59.        
  60.      
  61.        
  62.       
  63.     < bean    class = "org.springframework.scheduling.quartz.SchedulerFactoryBean" >   
  64.         < property   name = "triggers" >   
  65.             < list >   
  66.                 < ref   local = "jobOneSimpleTrigger" />   
  67.                 < ref   local = "jobTwoSimpleTrigger" />   
  68.              list >   
  69.          property >   
  70.      bean >   
  71.       
  72.  beans >   
[xml]  view plain copy
  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/beans http://www.springframework.org/schema/beans/spring-  
  5.   
  6. beans-2.0.xsd  
  7.             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd  
  8.             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">  
  9.   
  10.       
  11.       
  12.       
  13.       
  14.     <bean id="jobOne" class="test.job.JobOne" >  
  15.           
  16.     bean>  
  17.       
  18.       
  19.       
  20.     <bean id="jobOneDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
  21.         <property name="targetObject" ref="jobOne"/>  
  22.         <property name="targetMethod" value="execute"/>  
  23.         <property name="concurrent" value="true" />  
  24.     bean>  
  25.       
  26.       
  27.       
  28.     <bean id="jobOneSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">  
  29.         <property name="jobDetail" ref="jobOneDetail" />  
  30.         <property name="startDelay"><value>0value>property>  
  31.         <property name="repeatInterval"><value>1000value>property>  
  32.     bean>  
  33.       
  34.       
  35.       
  36.       
  37.       
  38.     <bean id="jobTwo" class="test.job.JobTwo" >  
  39.           
  40.     bean>  
  41.       
  42.       
  43.       
  44.     <bean id="jobTwoDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">  
  45.         <property name="targetObject" ref="jobTwo"/>  
  46.         <property name="targetMethod" value="execute"/>  
  47.         <property name="concurrent" value="true" />  
  48.     bean>  
  49.       
  50.       
  51.       
  52.     <bean id="jobTwoSimpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">  
  53.         <property name="jobDetail" ref="jobTwoDetail" />  
  54.         <property name="startDelay"><value>0value>property>  
  55.         <property name="repeatInterval"><value>1000value>property>  
  56.     bean>  
  57.       
  58.       
  59.       
  60.      
  61.       
  62.       
  63.     <bean  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">  
  64.         <property name="triggers">  
  65.             <list>  
  66.                 <ref local="jobOneSimpleTrigger"/>  
  67.                 <ref local="jobTwoSimpleTrigger"/>  
  68.             list>  
  69.         property>  
  70.     bean>  
  71.       
  72. beans>  



MAIN类:

Java代码
  1. package  test.job;  
  2.   
  3. import  org.springframework.context.ApplicationContext;  
  4. import  org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public   class  JobTest {  
  7.     private   ApplicationContext ac;  
  8.   
  9.     public  JobTest(ApplicationContext ac) {  
  10.         this .ac = ac;  
  11.     }  
  12.     /**  
  13.      * @param args  
  14.      */   
  15.     public   static   void  main(String[] args) {  
  16.         JobTest job = new  JobTest( new  ClassPathXmlApplicationContext("applicationContext.xml" ));  
  17.           
  18.   
  19.     }  
  20.   
  21. }  
[java]  view plain copy
  1. package test.job;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5.   
  6. public class JobTest {  
  7.     private  ApplicationContext ac;  
  8.   
  9.     public JobTest(ApplicationContext ac) {  
  10.         this.ac = ac;  
  11.     }  
  12.     /** 
  13.      * @param args 
  14.      */  
  15.     public static void main(String[] args) {  
  16.         JobTest job = new JobTest(new ClassPathXmlApplicationContext("applicationContext.xml"));  
  17.           
  18.   
  19.     }  
  20.   
  21. }  



测试结果: 

当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不会被阻塞) 

你可能感兴趣的:(java)