在我们使用一个Tomcat
实现了多端口多域名访问项目后。如果配置不当,随之而来的问题就是Tomcat
启动时项目重复加载,同一个项目会被加载多次;如果一个Tomcat
里面的项目较多或者服务器的配置低,就会引发服务器的运行严重缓慢,占用很多系统资源,很容易就出现了内存溢出。
演示环境
- Tomcat 8.5
导致的原因
我们在配置项目通过域名访问的时候,会有这样的配置:
<Host name="www.jerome.xin" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
<Context docBase="/project" path=""/>
</Host>
因为我们同时配置了Host
标签的appBase
和Context
标签的docBase
,所以当启动Tomcat
的时候,加载到<Host></Host>
的时候,就会去加载appBase
配置路径下的项目,当加载到<Context>
的时候,又加载了一次docBase
配置路径下的项目;然后Tomcat
继续按照配置文件执行,直到完成。
appBase
与docBase
区别
-
appBase
是指定虚拟主机的目录,可以指定绝对目录,也可以指定相对于的相对目录。如果没有此项,默认为/webapps
目录下。 -
docBase
是指定Web应用的文件路径。可以给定绝对路径,也可以给定相对于Host
的appBase
属性的相对路径。如果Web应用采用开放目录结构,那就指定Web应用的根目录;如果Web应用是个WAR文件,那就指定WAR文件的路径。
解决办法
webapps
下只有一个项目
当webapps
目录下只有一个项目的时候,我们只需要这样配置就可以避免项目的重复加载:
<Host name="www.jerome.xin" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
<Context docBase="/project" path="" name="/project"/>
</Host>
当有多个项目时
因为我们上面说了,在我们不指定appBase
的时候,默认取用/webapps
作为虚拟主机的目录。所以我们把另外的项目放到/webapps
下面时,启动Tomcat
的时候,还是会加载项目的。所以我们需要新建一个目录来存放我们的其它项目。比如新建一个/myapps
与/webapps
同级的目录,将项目放到里面,我们只需要做这样的更改:
<Host name="firstapp.jerome.xin" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
<Context docBase="../myapps/project1" path=""/>
</Host>
<Host name="secondapp.jerome.xin" unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
<Context docBase="../myapps/project2" path=""/>
</Host>
我们上面的配置Host
的时候并没有使用appBases
标签,而只是配置了docBase
,当然为了避免出错这里也可以使用绝对路径来配置。
总结
我们上面已经完美的解决了项目重复加载的问题,当多个项目部署在同一个Tomcat
容器中,配置域名访问的时候就不会导致资源重复加载。
原文链接:Tomcat 重复加载项目