一、问题描述:
本来一个定时任务在一定时间下只会创建一个线程去执行,
但服务器上的项目却创建了4个线程去执行,导致数据重复创建。
二、问题排查:
1,我查看了项目本身的web.xml配置
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:config/applicationContext.xml</param-value> </context-param> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:config/springMvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
context-param和servlet下的param-value里的配置文件是否被重复加载,导致实例化多个对象。
但web.xml的配置并没有错。
2,我测试本地代码。
在本地测试代码后,发现定时任务只被创建了1次。所以我怀疑服务器配置有问题。
3,发现问题所在原因:
下面是服务器端tomcat下的service.xml配置,域名的配置
<Host name="www.xxx.com" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context docBase="xxx" path="" reloadable="true"/> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> <Host name="xxx.com" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context docBase="xxx" path="" reloadable="true"/> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host>
Host标签下appBase=""和context标签下的 docBase=""属性配置导致的。
下面是个人的理解:appBase="webapps"表示:该目录下的项目都会自动部署
docBase=“”部署指定路径下的项目。
当docBase下的路径和appBase里的项目路径重复时,会被部署两次,导致执行定时任务时创建多个线程。
但是如果这样的话,我项目路径时,究竟访问的是哪个?还有如果被部署两次的话,但webapps下只有一个项目文件夹,不理解。
我目前的解决方案:删除了一个host标签块,将项目转移到其它路径,修改docBase的路径(docBase改为了绝对路径)。
修改(service.xml)部分配置如下:
<Host name="www.xxx.com" appBase="webapps" unpackWARs="true" autoDeploy="true"> <Context docBase="/hom/tomcat/xxx" path="" reloadable="true"/> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host>
绝对路径里的xxx为项目名
另外也顺便解决了另一个bug:javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidDataSourceStat
阿里的druid报错问题。