在tomcat 6 / Ubuntu 10.04LTS上部署时,Quartz作业运行两次

时间:2011-08-28 18:47:04

标签: spring tomcat6 quartz-scheduler ubuntu-10.04

我运行一个基于Spring Framework / SmartGWT的web-app,现在添加了一个Quartz作业。该工作应该每天凌晨2点运行,并从数据库表中挑选获胜者。从我的日志中我看到它同时运行两次,因为正如你所看到的,日志重叠:

Generating winners of yesterday...
Generating winners of yesterday...
winning id's: 15
done, mail queue is filled.

winning id's: 18
done, mail queue is filled.

我的applicationContext.xml如下所示:

<!-- initiates and calls the job -->  
<beans:bean id="GenerateWinnersAndFillMailingQueueJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> 
  <beans:property name="targetObject" ref="GenerateWinnersAndFillMailingQueueJobExecutor"/>  
  <beans:property name="targetMethod" value="execute"/> 
</beans:bean>  
<!-- here's where we use the Cron like scheduling expression      to define when the bean is run. -->  
<beans:bean id="GenerateWinnersAndFillMailingQueueJob" class="org.springframework.scheduling.quartz.CronTriggerBean"> 
  <beans:property name="jobDetail" ref="GenerateWinnersAndFillMailingQueueJobDetail"/>  
  <!-- run every morning at 2AM -->  
  <beans:property name="cronExpression" value="0 0 2 * * ?"/> 
</beans:bean> 
... another quartz jobs is defined here, omitted for clarity ...
<beans:bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 
  <beans:property name="triggers"> 
    <beans:list> 
      <beans:ref bean="GenerateWinnersAndFillMailingQueueJob"/>  
      <beans:ref bean="SendEmailsFromMailQueueJob"/> 
    </beans:list> 
  </beans:property> 
</beans:bean> 

我真的没有看到这里有什么问题,这是一个非常简单的用例。当我在本地测试时,在配备GWT开发模式的服务器上,它可以工作。只有在Ubuntu 10.04 LTS上部署到Tomcat6时,我才会遇到这个问题。

有什么想法吗?

**编辑:在评论提示之后,增加日志级别,似乎Spring正在运行两次。重新启动tomcat服务器会显示两个Springs被实例化,相隔约4秒。

2011-08-29 08:49:22,567 {ABSOLUTE}  INFO XmlWebApplicationContext,Thread-9:1002 - Closing Root WebApplicationContext: startup date [Sun Aug 28 20:53:39 CEST 2011]; root of context hierarchy
2011-08-29 08:49:22,569 {ABSOLUTE}  INFO DefaultLifecycleProcessor,Thread-9:345 - Stopping beans in phase 2147483647
2011-08-29 08:49:22,589 {ABSOLUTE}  INFO QuartzScheduler,Thread-9:537 - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED paused.
2011-08-29 08:49:22,592 {ABSOLUTE}  INFO DefaultListableBeanFactory,Thread-9:422 - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@12e14ebc: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,MerchantSimpleJsonWebservice,merchantDao,AdvertisementSimpleJsonWebservice,advertisementDao,ContactFormSubmitsSimpleJsonWebservice,contactFormSubmitsDao,PlayerCustomJsonWebservice,PlayerCustomJsonWebserviceImpl,submitSolutionDao,GenerateWinnersAndFillMailingQueueJobExecutor,GenerateWinnersAndFillMailingQueueJobDetail,GenerateWinnersAndFillMailingQueueJob,SendEmailsFromMailQueueJobExecutor,SendEmailsFromMailQueueJobDetail,SendEmailsFromMailQueueJob,org.springframework.scheduling.quartz.SchedulerFactoryBean#0,org.springframework.security.web.PortMapperImpl#0,org.springframework.security.web.context.HttpSessionSecurityContextRepository#0,org.springframework.security.authentication.ProviderManager#0,org.springframework.security.access.vote.AffirmativeBased#0,org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0,org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator#0,org.springframework.security.authentication.AnonymousAuthenticationProvider#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.config.http.UserDetailsServiceInjectionBeanPostProcessor#0,org.springframework.security.filterChainProxy,sessionAuthenticationStrategy,sessionRegistry,propertyConfigurer,org.springframework.security.authentication.dao.DaoAuthenticationProvider#0,org.springframework.security.authentication.DefaultAuthenticationEventPublisher#0,org.springframework.security.authenticationManager,saltSource,dataSource,jdbcTemplate,passwordEncoder,jdbcUserService,loggerListener,formLoginFilter,authenticationEntryPoint,accessDeniedHandler,concurrencyFilter]; root of factory hierarchy
2011-08-29 08:49:22,601 {ABSOLUTE}  INFO SchedulerFactoryBean,Thread-9:760 - Shutting down Quartz Scheduler
2011-08-29 08:49:22,601 {ABSOLUTE}  INFO QuartzScheduler,Thread-9:616 - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED shutting down.
2011-08-29 08:49:22,602 {ABSOLUTE}  INFO QuartzScheduler,Thread-9:537 - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED paused.
2011-08-29 08:49:22,603 {ABSOLUTE}  INFO QuartzScheduler,Thread-9:688 - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED shutdown complete.
2011-08-29 08:49:22,882 {ABSOLUTE}  INFO XmlWebApplicationContext,Thread-9:1002 - Closing Root WebApplicationContext: startup date [Sun Aug 28 20:53:34 CEST 2011]; root of context hierarchy
2011-08-29 08:49:22,883 {ABSOLUTE}  INFO DefaultLifecycleProcessor,Thread-9:345 - Stopping beans in phase 2147483647
2011-08-29 08:49:22,903 {ABSOLUTE}  INFO QuartzScheduler,Thread-9:537 - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED paused.
2011-08-29 08:49:22,904 {ABSOLUTE}  INFO DefaultListableBeanFactory,Thread-9:422 - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@402fb002: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,MerchantSimpleJsonWebservice,merchantDao,AdvertisementSimpleJsonWebservice,advertisementDao,ContactFormSubmitsSimpleJsonWebservice,contactFormSubmitsDao,PlayerCustomJsonWebservice,PlayerCustomJsonWebserviceImpl,submitSolutionDao,GenerateWinnersAndFillMailingQueueJobExecutor,GenerateWinnersAndFillMailingQueueJobDetail,GenerateWinnersAndFillMailingQueueJob,SendEmailsFromMailQueueJobExecutor,SendEmailsFromMailQueueJobDetail,SendEmailsFromMailQueueJob,org.springframework.scheduling.quartz.SchedulerFactoryBean#0,org.springframework.security.web.PortMapperImpl#0,org.springframework.security.web.context.HttpSessionSecurityContextRepository#0,org.springframework.security.authentication.ProviderManager#0,org.springframework.security.access.vote.AffirmativeBased#0,org.springframework.security.web.access.intercept.FilterSecurityInterceptor#0,org.springframework.security.web.access.DefaultWebInvocationPrivilegeEvaluator#0,org.springframework.security.authentication.AnonymousAuthenticationProvider#0,org.springframework.security.web.savedrequest.HttpSessionRequestCache#0,org.springframework.security.config.http.UserDetailsServiceInjectionBeanPostProcessor#0,org.springframework.security.filterChainProxy,sessionAuthenticationStrategy,sessionRegistry,propertyConfigurer,org.springframework.security.authentication.dao.DaoAuthenticationProvider#0,org.springframework.security.authentication.DefaultAuthenticationEventPublisher#0,org.springframework.security.authenticationManager,saltSource,dataSource,jdbcTemplate,passwordEncoder,jdbcUserService,loggerListener,formLoginFilter,authenticationEntryPoint,accessDeniedHandler,concurrencyFilter]; root of factory hierarchy
2011-08-29 08:49:22,913 {ABSOLUTE}  INFO SchedulerFactoryBean,Thread-9:760 - Shutting down Quartz Scheduler
2011-08-29 08:49:22,914 {ABSOLUTE}  INFO QuartzScheduler,Thread-9:616 - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED shutting down.
2011-08-29 08:49:22,914 {ABSOLUTE}  INFO QuartzScheduler,Thread-9:537 - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED paused.
2011-08-29 08:49:22,915 {ABSOLUTE}  INFO QuartzScheduler,Thread-9:688 - Scheduler org.springframework.scheduling.quartz.SchedulerFactoryBean#0_$_NON_CLUSTERED shutdown complete.
2011-08-29 08:49:26,484 {ABSOLUTE}  INFO ContextLoader,main:187 - Root WebApplicationContext: initialization started

稍后,似乎启动了两个Spring实例:

2011-08-29 08:49:26,484 {ABSOLUTE}  INFO ContextLoader,main:187 - Root WebApplicationContext: initialization started
...
2011-08-29 08:49:31,221 {ABSOLUTE}  INFO ContextLoader,main:187 - Root WebApplicationContext: initialization started

造成这种情况的原因是什么,以及要做什么?

3 个答案:

答案 0 :(得分:7)

我修好了,不仅石英跑了两次,而且我的应用程序已经部署了两次。这是因为Tomcat文档中有以下内容:

  

使用自动部署时,XML Context文件定义的docBase应位于appBase目录之外。如果不是这种情况,则可能会遇到部署Web应用程序的困难,或者可能会部署应用程序两次。 deployIgnore属性可用于避免这种情况。

     

最后,请注意,如果要在server.xml中显式定义上下文,则应该关闭自动应用程序部署或仔细指定deployIgnore。否则,每个Web应用程序将被部署两次,这可能会导致应用程序出现问题。

我遵循了如何让mod_jk工作的教程,this tutorial包含了这个缺陷。

答案 1 :(得分:3)

对我来说,自动部署是个问题,要禁用它,我必须在server.xml中的 host 元素上指定以下属性:

deployOnStartup="false"
autoDeploy="false"

所以我的主机元素看起来像这样:

  <Host name="localhost" 
        deployOnStartup="false"  
        appBase="webapps" 
        unpackWARs="false" 
        autoDeploy="false">

我发现this post以不同的方式详细说明了问题,这有助于我解决这个问题。

答案 2 :(得分:0)

您最终是否在Ubunut计算机上的一个Tomcat实例中运行了多个应用程序?我想我记得Quartz有一些静态代码,它将通过一个Java VM中的所有应用程序共享。