麻雀虽小,五脏俱全,Tomcat 提供的自动部署、自动重加载、自动编译功能,可谓是让人又爱又恨。接下来就对这三者做一个介绍,文章中会Copy一些官方文档中的说法。
If you are using the standard Host implementation, the following actions take place automatically when Catalina is first started, if the deployOnStartup property is set to true (which is the default value):
- Any XML file in $CATALINA_BASE/conf/[engine_name]/[host_name] is assumed to be a context XML descriptor containing a Context element (and its associated sub-elements) for a single web application. The web applications associated with each of these context XML descriptor files will be deployed first. 在$CATALINA_BASE/conf/[engine_name]/[host_name] 目录下,任何的xml文件只要是以<Context />元素的为root元素的xml文件,都会被认为是一个web应用,并且应用的名称就是xml文件的名称。例如server.xml中<Engine name="Catalina" > <Host name="localhost" /> </Engine> 那么在Tomcat启动后就会在$CATALINA_BASE/conf/目录下创建Catalina/localhost目录,前提是这两个目录没有存在,存在的话,就不用创建了。然后会扫描这个目录下的xml文件,如果xml文件是以Context元素为根元素的话,就会将这个文件认为一个web应用,进行部署。
The docBase attribute of this <Context> element must only be set if the docBase
is outside the Host‘sappBase. For web applications located inside the
Host‘s appBase, the docBase will be the name of the XML file with ".xml" replaced with
".war" for a web application archive or the name of the XML file with
".xml" removed for a directory. 如果你的web应用放在了host的扫描目录appBase目录之外,就需要<Context docBase="指定应用的位置"/>
The path attribute must not be set. The
context path used will be a slash character ("/") followed by the
name of the XML file (less the .xml extension). Multi-level context paths may
be defined using #, e.g.foo#bar.xml for a context path of /foo/bar. The default web application that has a
context path of / may be defined by using a file
called ROOT.xml. path元素就不必去设定了,如果你的web应用是test.war,就会在context描述符目录下生成一个test.xml文件,对应的path就是/test。如果是一个多级目录的应用,例如将xml文件放在了$CATALINA_BASE/conf/Catalina/localhost/foo/bar.xml中,就会将/foo/bar作为应用的访问路径。 - Any
web application archive file within the Host‘s appBase directory that has not already been deployed as a result of a
context XML descriptor, does not have a corresponding directory of the same
name (without the ".war" extension), and is not excluded by deployIgnore will be deployed next. The context path
used will be a slash character ("/") followed by the web application
archive name less the ".war" extension. The one exception to this
rule is that a web application archive named "ROOT.war" will be
deployed with a context path of /. Multi-level
contexts may be defined by using #, e.g. use a WAR named foo#bar.war for a context path of /foo/bar.
If the unpackWARs attribute is true, the web application archive file will be expanded to a directory of the
same name (without the ".war" extension".
Note: If you re-deploy an updated WAR file while Tomcat is stopped, be sure to
delete the associated expanded directory before restarting Tomcat, so that the
updated WAR file will be re-expanded when Tomcat restarts. 如果指定了<Host
unpackWARs="true" />,部署应用时,就会将test.war解压成test目录。你要是想升级test应用,就需要将tomcat shutdown,并删除test.war和test目录。
Any web application archive file within the Hosts‘s appBase directory that does not have a
corresponding context XML descriptor (with a ".xml" extension rather
than a ".war" extension) in$CATALINA_BASE/conf/[engine_name]/[host_name] will be scanned to see if it contains a
context XML descriptor (located at /META-INF/context.xml) and if one is found the descriptor will be
copied to the$CATALINA_BASE/conf/[engine_name]/[host_name] directory and renamed. 在host‘s
appbase目录下的war包,不会为之生成一个上下文描述符文件。如果是一个web应用的目录的话就会的。所以如果你将test.war放到appBase目录,并指定了unpackWARS=true时,也会生成一个上下文描述符文件的。 - Finally,
any sub-directory within the Host‘s appBase that has not already been deployed as a result of a context XML
descriptor and is not excluded by deployIgnore will be deployed. The context path used will be a slash character
("/") followed by the directory name, unless the directory name is
ROOT, in which case the context path will /.
Multi-level contexts may be defined by using #, e.g. use a directory namedfoo#bar for a context path of /foo/bar.
Any directory within the Hosts‘s appBase directory
that does not have a corresponding context XML descriptor in $CATALINA_BASE/conf/[engine_name]/[host_name] will be scanned to see if it contains
a context XML descriptor (located at /META-INF/context.xml) and if one is found the descriptor will be
copied to$CATALINA_BASE/conf/[engine_name]/[host_name] and renamed. 在Host的appBase目录下,也可以将应用放在多级目录下。这样生成的上下文描述符就是在相应的多级目录下,path也是了。
=================================
自动部署
In
addition to the automatic deployment that occurs at startup time, you can also
request that new XML configuration files, WAR files, or sub-directories that
are dropped in to the appBase (or$CATALINA_BASE/conf/[engine_name]/[host_name] in the case of an XML configuration
file) directory while Tomcat is running will be automatically deployed,
according to the rules described above. The auto deployer will also track web
applications for the following changes(下面几种情况下,都会触发自动编译):
- An
update to the WEB-INF/web.xml file will trigger a reload of the web application
更新了应用的web.xml - Deleting
a WAR file will trigger an undeploy of the application with the removal of any
associated expanded directory, context file and work directory. Any current user
sessions will not be persisted. 如果删除了war包就会触发解部署操作。解部署时会删除应用解压后的目录、context描述符文件、work/[engine]/[host]/下的对应目录(也称为work目录)。 - Deleting
a directory will trigger an undeploy of the application with the removal of any
associated context file and work directory. Any current user sessions will not
be persisted. If there is an associated WAR file, it will not be deleted and
the application will be redeployed from the WAR file the next time the auto
deployer checks for changes. 删除host appbase下的目录,就会删除与之关联的context文件和work目录,session 信息就可能完蛋了。但是关联的war不会被移除。 - Deleting
a context file will trigger an undeploy of the application with the removal of
any associated work directory. Any current user sessions will not be persisted.
If there is an associated WAR file and/or directory, they will not be deleted
and the application will be redeployed from the WAR file (or from directory if
there is no WAR file) the next timie the auto deployer checks for changes. 移除上下文文件时,也就触发解部署操作。但只会移除work目录,不会移除与之关联的应用目录和war包。 - Updating
a WAR file will trigger an undeploy of the application with the removal of any
associated expanded directory, context file and work directory. Any current
user sessions will not be persisted. 更新war包(tomcat会周期性的检查文件或者目录的时间戳,从而加以判断的)会触发解部署操作。 - Updating
a directory (not the directory contents) will trigger an undeploy of the
application with the removal of any associated context file and work directory.
Any current user sessions will not be persisted. The application will be
redeployed the next time the auto deployer checks for changes. - Updating
a context file will trigger an undeploy of the application with the removal of
any associated work directory. Any current user sessions will not be persisted.
The application will be redeployed the next time the auto deployer checks for
changes.
对上述几种情况做一个小小的总结:启用自动部署功能,只需要设置<Host autoDeploy=”true” />就可以了。另外要说明的是,如果在想要添加一个web应用,只需要将web应的目录或者war包加入的appBase目录下,就会自动的进行部署了。
自动部署功能,会监控web.xml、context.xml、应用的目录和war包。这些内容的时间戳发生了变化,就会认为是应用发生了添加、改变或者移除,就会触发部署解部署操作。
针对会触发解部署的操作中,根据重要性,有一个排序:war>web应用目录>context.xml>work目录 。由war,web,context.xml触发的解部署操作,会移除排他们后面的内容。
另外,如果想要了解这部分的源码,可以从HostConfig.java 中的public void
check(path)方法看起。
When
using automatic deployment, the docBase defined
by an XML Context file should be
outside of the appBasedirectory. If this is not the case,
difficulties may be experienced deploying the web application or the
application may be deployed twice. The deployIgnore attribute can be used to avoid this situation.
Finally,
note that if you are defining contexts explicitly in server.xml, you should
probably turn off automatic application deployment or specify deployIgnore carefully. Otherwise, the web
applications will each be deployed twice, and that may cause problems for the
applications.
自动重加载
自动重加载:是说tomcat中已经将web应的类文件加载完毕了,但是有些类文件发生了改变,在不重启tomcat的情况下,要应用到新的class。也就是热部署。想要启用这个功能,需要将<Context
reloadable=”true” />启用。
Set to true
if you want Catalina to monitor classes in /WEB-INF/classes/
and /WEB-INF/lib
for changes, and automatically reload the web application if a change is
detected. This feature is very useful during application development, but it
requires significant runtime overhead and is not recommended for use on
deployed production applications. That‘s why the default setting for this
attribute is false. You
can use the Manager web application, however, to trigger reloads of deployed applications on
demand.
上面的说这个参数,管理的范围是WEB-INF/lib目录下的jar包,以及WEB-INF/classes目录下下的class文件。如果这些发生了变化,就会触发热部署(自动重加载)的。但是这在生产环境下是不推荐的。
另外说一点热部署相关的内容:因为ClassLoader有一个特点,就是一个class加载后,就会在ClassLoader中有记录的,不会再去加载第二遍的,所以要实现热部署功能,肯定是换了另外一个类加载器的。
自动编译
自动编译,是针对JSP文件的。开发过程中,修改了jsp文件,不需要重启tomcat,就能应用上最新的文件了,为开发节省了不少的时间。管理jsp文件的编译的是一个JspServlet。它有三个重要的参数:development、checkInterval、modificationTestInterval。
在说这个三个参数前,先了解一下jsp编译:
JSP后台编译:如果你修改了jsp文件后,就会进行后台编译,来将文件重新编译一下。
Recompile Jsp当inclued文件发生变化:一个JSP文件可以使用<include
/>来引入其他的jsp文件(称为子jsp),例如a.jsp中使用<jsp:include />引入了b.jsp如果子b.jsp发生了改变,就会重编译a.jsp文件。
development:是控制是否开发模式或者生产模式。其实就是来控制jsp编译的。
Development=true时,就会参考modificationTestInterval的设置,这个值是为了延迟jsp文件的冲编译。这个参数的默认值是4s,当jsp文件发生了改变,4秒后就会重新编译。如果你将这个值设置为0,就不会延迟了,但是会在每一次访问就会编译一次。
Development=false时,就会参考checkInterval的设置了。如果这个参数的值是大于0,就会启动后台编译功能,按照指定的间隔对文件进行编译。默认值是0 。