问题描述

如果选择定时任务,那么Quartz是一个不错的框架,但是在使用的过程中,莫名发现Quartz定时任务在指定时间被执行了两次。
 

问题原因

Tomcat的配置文件conf/server.xml中:

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
    <Context path="" docBase="/test" />
</Host>
  • 1
  • 2
  • 3
  • 4

其中<Host/>告诉Tomcat,在启动的时候加载webapps下的所有项目工程文件,<Context/>又让Tomcat再加载了一遍(一般情况下配置<Context/>,主要是由于想域名访问时将工程名去掉的原因配置),这种情况下会导致工程中的quartz定时被两次触发,执行两次。
 

解决方式

一般有两种解决方式:

  • 修改Tomcat的配置文件conf/server.xml
  • Quartz配置信息提取出来,单独存成一个文件,比如applicationContext-quartz.xml,然后修改该项目的配置文件web.xml,让web容器启动时,可以加载该文件

一般采用第一种解决方式,将Tomcat的配置文件conf/server.xml修改为:

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="false" deployOnStartup="false">
    <Context path="" docBase="/test"/>
</Host>
  • 1
  • 2
  • 3
  • 4

其中:

  • autoDeploy:是否允许自动部署,默认值是true,即表示 Tomcat 会自动检测appBase目录下面的文件变化从而自动应用到正在运行的 Web 应用程序。
  • deployOnStartup="false",表示Tomcat服务器启动时, 不会自动发布appBase目录下所有的Web应用。

但是这样虽然解决了Quartz的执行两次的问题,但也存在另一个问题——无法解压war。就是war包放到webapps目录下,不会自动解压生成项目文件夹,你所看到的项目文件夹是历史文件夹

所以,这是一个不断修改conf/server.xml的过程——当需要解压文件夹的时候,修改成true,解压完成后,改成false,记得重启Tomcat。