Tomcat 配置导致启动时,项目加载两次的解决办法

@zxniuniu   2019-05-11  
0 评论   116 浏览

现象: 

Tomcat 在启动的时候,由于配置原因,导致工程会被加载两次,很容易出现内存溢出。如果有定时任务,也可能导致定时任务执行两次,从而出现问题。

原因: 

在tomcat/conf/server.xml配置虚拟目录引起,如下配置:

<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
      <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" 
	   pattern="%h %l %u %t &quot;%r&quot; %s %b" 
	   prefix="localhost_access_log" suffix=".txt"/>
 
      <Context docBase="solo" path="/" reloadable="true" />
</Host>

首先介绍下 appBase 与 docBase 的区别

  • appBase 是指定虚拟主机的目录,可以指定绝对目录,也可以指定相对于Tomcat目录的相对目录,如果没有此项,默认为webapps
  • docBase是指定Web应用的文件路径,可以给定绝对路径,也可以给定相对于Host的appBase属性的相对路径;如果Web应用采用开放目录结构,那就指定Web应用的根目录;如果Web应用是个WAR文件,那就指定WAR文件的路径

分析:

  1. 根据Tomcat规则,当为 Host 容器设置了 appBase 属性时,Tomcat 会在启动时自动加载 appBase 指定目录下的所有合法工程;
  2. 同时 Context 的 docBase 属性设置了Tomcat 默认工程, 所以指定的 工程又会被加载一次;
  3. 根据server.xml配置,Tomcat首先根据的配置内容生成第一个StandardContext对象,加载一次项目。
  4. 然后,再根据Host/appBase的配置对webapps下面的项目生成第二个StandardContext,再加载一次项目。

Tomcat针对同一项目生成两个StandardContext的原因就是因为他们的名字不同,Tomcat认为是两个Context,所以加载了两次。

上面,我们在Host标签里配置了appBase="webapps",tomcat加载了一次应用。同时, 在里配置了一次docBase,tomcat又加载了一次。 从而,导致项目会加载二次。

解决方法:

方法一

直接把项目放到webapps下,指定appBase="webapps",不指定配置内容,即注释掉

方法二

不把项目放入webapps下,在tomcat目录下新建文件夹,如solo,去掉appBase设置(经测试,设置appBase="",貌似也不行),然后配置标签:

<Context docBase="D:/Tomcat/solo" path="" reloadable="true"/>   

方法三

直接把项目目录放到webapps下,并修改项目名称为ROOT,指定appBase="webapps",不指定配置内容,即注释掉

结论,如果Tomcat仅加载了少数的项目,可以使用方法一、三。另外,方法二也存在弊端,即如果项目中的链接或者图片是绝对路径的话,那么带有项目名称的绝对路径是无法正常使用的。

参见:https://blog.csdn.net/mrliar17/article/details/80898914
https://segmentfault.com/a/1190000002985203


评论列表

添加新评论