Tomcat Web 应用程序部署

Tomcat Web应用程序部署

Introduction

部署是这个团队用于安装一个Web应用程序到Tomcat服务器的过程。

Web应用程序在Tomcat服务器的部署通常有两种方式.

·         静态的; Web应用程序在Tomcat启动前就安装好

·         动态的; 使用Tomcat Manager这个Web应用程序或者操纵已经部署的Web应用程序

Tomcat Manager 是一款工具它提供基于以URL为基础的Web应用程序部署特性。也有一种工具被称为Client Deployer, 它是一种基于脚本的“命令shell”,它与这个Tomcat Manager 交互,但是提供另外的一些功能,像编译和验证Web应用程序还有打包Web应用程序到一个WAR文件。

 

 

A word on Contexts[涉及上下文的一个词汇]

在谈到关于Web应用程序部署的时候,这个Context上下文的概念是必须明白的。. 一个上下文在Tomcat中称之为Web应用程序。

在Tomcat中为了配置一个上下文,一个上下文描述器文件是必须的。一个Context描述器是一个简答的XML文件,它包含了一个与Tomcat有关的Context的配置,例如命naming resources 或者session manager 配置.在Tomcat的早期版本这个上下文描述器配置的内容通常存储在Tomcat的主配置文件Server.xml里面。但是现在不推荐这样做了(虽然目前仍然支持)。

上下文描述不仅仅帮助Tomcat知道如何配置上下文,同时其他工具像这个Tomcat Manager和TCD通常使用这些上下文描述器去适当地完成他们的任务。

上下文描述器的位置如下:

1.      $CATALINA_BASE/conf/[enginename]/[hostname]/context.xml

2.      $CATALINA_BASE/webapps/[webappname]/META-INF/context.xml

第一种方式文件被命名为 [webappname].xml 但是在第二中方式文件被命名为context.xml. 如果上下文描述器没有被提供,Tomcat将使用缺省值配置应用程序的上下文。.

 

Deployment on Tomcat startup[Tomcat启动的时候部署]

如果你没有兴趣采用Tomcat Manager, or TCD 部署你的应用程序, 那么你需要采用静态方式部署你的应用程序到Tomcat, 跟随Tomcat的启动[Tomcat启动的时候会一并启动你静态部署的应用程序]。你部署的应用程序的位置要和特定虚拟主机的appBase属性描述位置一致[webapps]. 你可以拷贝一个应用程序目录[就是未压缩目录]到这个位置或者一个经过压缩的应用程序资源文件[.WAR].

Web应用程序存在的位置由虚拟主机(缺省情况下主机名是"localhost")的appBase属性(缺省的appBase 是 "$CATALINA_BASE/webapps")指定。

它们仅仅在虚拟主机的deployOnStartup 属性值是true的条件下随着Tomcat的启动被自动部署。

如果是那样的话Tomcat启动的时候将遵循以下部署顺序:

1.      任意上下文描述器文件将首先被部署。

2.      没有被任何上下文描述器引用的解压缩的Web应用程序将然后被部署。如果它们与个appBase描述路径下的.WAR文件关联并且它这个.WAR文件比展开的这个目录新,那么这个展开的目录将被删除然后这个Web应用程序将从这个.WAR文件重新部署。

3.      .WAR 文件将被部署。

Note again that for each deployed web application, a Context Descriptor will be created unless one exists already.

 

Deploying on a running Tomcat server[Tomcat服务器运行期间部署]

部署一个Web应用程序到一个运行中的Tomcat服务器是可行的。

如果这个虚拟主机的autoDeploy 属性是true,这个主机将尝试去动态地部署和更新Web应用程序。.

autoDeploy设置为 "true" ,一个运行中的Tomcat 允许:

·         部署拷贝到这个虚拟主机appBase指定目录下的.WAR文件.

·         部署拷贝到这个虚拟主机appBase指定目录下的站看的Web应用程序.

·         当一个较新的.WAR文件被提供的时候重新部署Web应用程序,在这种情况下这个展开的Web应用程序目录将被删除,这个较新的.WAR文件将再次被展开。但是注意如果这个虚拟主机被配置为.WAR文件不被展开(使用unpackWARs=false),那么这个展开行为就是无法看到的。

·         如果一个Web应用程序的/WEB-INF/web.xml或者其它被定义为WatchedResource的文件被更改,那么将重新加载Web应用程序。

·         如果一个Web应用程序被部署的上下文描述器文件被更新,那么重新部署这个Web应用程序。

·         如果用于Web应用程序的全局的或者每个虚拟主机的上下文描述器文件被更新那么重新部署这个Web应用程序。

·         如果一个上下文描述器文件(文件名与部署的Web应用程序的上下文路径相符合)被添加到$CATALINA_BASE/conf/[enginename]/[hostname]/这个目录那么重新部署这个Web应用程序。

·         如果一个Web应用程序的部署目录(docBase属性指定的目录)被被删除那么撤销部署这个Web应用程序。注意在Windows系统上,这里假定防锁(参考上下文配置)功能是启用的。否则是不可能去删除一个运行的Web应用程序的资源的。

注意Web应用程序的重新加载也能够被配置在加载器[loader],那样的话被加载的类的改变将被跟踪。

 

实践

首先理解分析一下Tomcat的核心配置文件

Tomcat服务器是由一系列可配置的组件构成,其中核心组件是Catalina Servlet容器,它是所有其他Tomcat组件的顶层容器。Tomcat的组件可以在<CATALINA_HOME>/conf/server.xml文件中进行配置,每个Tomcat组件在server.xml文件中对应一种配置元素。以下代码呈现了各种Tomcat组件之间的关系:

<Server>

         <Service>

                   <Connector/>

                   <Engine>

                            <Host>

                                     <Context>

                                     </Context>

                            </Host>

                   </Engine>

         </Service>

</Server>

以上XML代码中,每个元素都代表一种Tomcat组件。

这些元素可分为四类。

1、  顶层元素类<Server>\<Service>

a)         Server元素类

                                       i.              <Server>元素代表整个Catalina Servlet容器,因此它在conf/server.xml文件中必须是单独的最外层元素,它的属性表示整个Servlet容器的特征。<Server>元素中可包含一个或多个<Service>元素和GlobalNamingResources元素。

b)         Service元素类

                                       i.              一个Service元素表示一个或者多个Connector元素组件的组合,这些Connector元素组件共享一个单独的Engine组件用于处理客户端到来的请求。可以有一个或多个Service元素。

2、  连接器元素类<Connector>

连接器元素类代表了介于客户与服务器之间的通信接口,负责将客户的请求发送个服务器,并将服务器的响应结果传递给客户。

a)         Http Connector

                                       i.              Http Connector元素表示一个支持HTTP/1.1协议的Connector组件.它除了他的执行ServletJSP页面的能力之外它使Catalina的功能能够成为一个独立的Web服务器。这个组件的一个实例在服务器的一个特定的TCP端口号上监听客户端到来的连接。一个或多个这样的Connector能被配置为单个Service的部件,附送到管理的Engine去执行请求处理和创建响应。

b)         AJP Connector

AJP Connector元素表示一个Connector组件,它通过这个AJP协议与一个Web Connector进行通信。这被用于你希望去整合Tomcat到一个存在的或新的Apache安装的情形。并且你希望Apache去处理Web项目包含的静态内容,并且或者利用ApacheSSL处理。

        

3、  容器元素类

容器元素类代表处理客户请求并生成响应的结果的组件,有3种容器类型元素,他们是EngineHostContext

3.1Engine组件为特定的Service组件处理所有客户请求,每个<Service>元素只能包含一个<Engine>元素。<Engine>元素处理在同一个<Service>中所有<Connector>元素接收到的客户请求。并且返回完整的响应给Connector作为最终的传输返回给客户端。

3.2Host组件为特定的虚拟主机处理所有客户请求,一个<Engine>元素中可以包含多个<Host>元素。每个<Host>元素定义了一个虚拟主机,它可以包含一个或多个Web应用。虚拟主机通常是一个网络名的关联,客户端使用虚拟主机的网络名可以连接到一个Tomato服务器。这个网络名必须在DNS服务器注册。

           在许多情况下,系统管理员希望关联多于一个网络名到相同的虚拟主机和应用程序,这个可以通过使用主机别名<Alias>来完成。

           一个或者多个Host元素被嵌套在一个Engine元素,在这个Host元素里面,对于与这个虚拟主机关联的web应用程序你能嵌套Context元素在它里面。与某个Engine关联的这些虚拟主机中的某一个必须有一个名字匹配Engine元素的defaultHost属性。

           客户端通常使用主机名来标识它希望连接的服务器。这个主机名也被包含在HTTP请求头。TomcatHTTP请求头提取这个主机名并且使用一个匹配名字查询一个Host。如果没有匹配被发现,这个请求被路由到缺省主机。

 

3.3Context组件为特定的Web应用处理所有客户请求。<Context>元素是使用最频繁的元素。每个<Context>元素代表了运行在虚拟主机上的单个Web应用程序,它运行在一个实际的虚拟主机内,每个Web应用程序是基于一个Web应用程序档案文件或者一个相应目录包含相应的解包内容。

           Web应用程序处理每个HTTP请求的选择方式是基于请求URI的最长可能前缀匹配原则,一旦被选择,Context将依照servlet mapping的定义来选择一个合适的Servlet来处理到来的请求。

           你可以定义多个Context元素,如果你需要的话。每个Context必须拥有一个唯一的Context名字。

一个<Host>元素中可以包含多个<Context>元素。

 

4、  嵌套类元素

嵌套类元素代表了可以加入到容器中的组件,如<Logger>元素、<Valve>元素和<Realm>元素。

 

Tomcat中各个组件之间的关系:

一个Server可以包含一个到多个Service

一个Service看一个包含多个连接器Connector和一个Engine

多个连接器共享一个Engine

同一个Engine中可以有多个Host.

同一个Host中包含多个Context

 

下面看一个具体的案例:

现有两个应用客户端访问地址分别为:

Http://localhost:8080/app1/index.jsp

Http://localhost:8080/app2/index.jsp

 

处理步骤说明:

1、  请求被8080端口监听的Connector1接收到

2、  Connector1把请求交给共享的Engine处理

3、  Engine根据HTTP请求头里面的主机头Host决定该交给那个虚拟主机处理,很明显这里主机头是locahost,因此交给locahost这个虚拟主机处理

4、  虚拟主机根据Context决定请求交给哪个应用程序上下文处理,这里客户端1发出的请求将交给app1处理。

 

 

示范:

静态部署这里不示范,这里示范动态部署。

一、通过拷贝到webapps目录来实现动态部署

我的d盘根目录有一Web应用程序app1:


 

先将其直接拷贝到webapps目录下:


 

观察Tomcat的日志输出:


 

如下:

信息: Deploying web application directory E:\WorkSpace\JavaWorkspace\Tomcat 7.0\webapps\app1

2012-6-3 23:18:31 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info

信息: Parsing configuration file [struts-default.xml]

2012-6-3 23:18:31 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info

信息: Parsing configuration file [struts-plugin.xml]

2012-6-3 23:18:31 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info

信息: Parsing configuration file [struts.xml]

说明拷贝进去的项目被自动部署了。

我们再次删除这个项目,但是提示:


 

这个是因为应用中的jar包被锁定的缘故,查看tomcatContext属性,如下:

http://localhost:8080/docs/config/context.html

antiJARLocking

If true, the Tomcat classloader will take extra measures to avoid JAR file locking when resources are accessed inside JARs through URLs. This will impact startup time of applications, but could prove to be useful on platforms or configurations where file locking can occur. If not specified, the default value isfalse.

antiJARLocking is a subset ofantiResourceLocking and therefore, to prevent duplicate work and possible issues, only one of these attributes should be set totrue at any one time.

我们修改conf/ context.xml,添加属性antiResourceLocking=true,如下:

<Context antiResourceLocking="true">

 

    <!-- Default set of monitored resources -->

    <WatchedResource>WEB-INF/web.xml</WatchedResource>

 

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->

    <!--

    <Manager pathname="" />

    -->

 

    <!-- Uncomment this to enable Comet connection tacking (provides events

         on session expiration as well as webapp lifecycle) -->

    <!--

    <Valve className="org.apache.catalina.valves.CometConnectionManagerValve" />

    -->

 

</Context>

 

再次删除app1,就不会有上面的提示了。删除app1后我们观察日志输出:

信息: Undeploying context [/app1]

2012-6-3 23:27:02 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks

严重: The web application [/app1] created a ThreadLocal with key of type [com.opensymphony.xwork2.inject.ContainerImpl$10] (value [com.opensymphony.xwork2.inject.ContainerImpl$10@3ca56f]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@191394e]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

2012-6-3 23:27:02 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks

严重: The web application [/app1] created a ThreadLocal with key of type [com.opensymphony.xwork2.inject.ContainerImpl$10] (value [com.opensymphony.xwork2.inject.ContainerImpl$10@3ca56f]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@149494e]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

2012-6-3 23:27:02 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks

严重: The web application [/app1] created a ThreadLocal with key of type [com.opensymphony.xwork2.inject.ContainerImpl$10] (value [com.opensymphony.xwork2.inject.ContainerImpl$10@3ca56f]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@6bbb36]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

2012-6-3 23:27:02 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks

严重: The web application [/app1] created a ThreadLocal with key of type [com.opensymphony.xwork2.inject.ContainerImpl$10] (value [com.opensymphony.xwork2.inject.ContainerImpl$10@3ca56f]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@d006a7]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

 

二、通过为Web应用程序添加一个特定的Context文件来实现动态部署

           我们找到以下位置:conf/Catalina/localhost,这个目录代表什么?

           Catalina代表server.xml文件里面配置的默认的Service的名称。

           Localhost代表Service里面的默认虚拟主机名称。

           我们现在就是要在这个虚拟主机里面部署我们的应用。

           做法:

1、  创建一个xml文件,文件名和Web应用名相同:app1.xml

2、  这个文件的内容如下:

a)         <Context path="/app1" docBase="d:/app1" debug="0" privileged="true" workDir="d:/app1work"></Context>

3、  将这个文件拷贝到conf/Catalina/localhost下面,完整路径就是conf/Catalina/localhost/app1.xml,这时Tomcat会自动扫描到这个文件然后根据里面的描述加载应用上下文的。

4、  观察现在的日志输出:

l  信息: Deploying configuration descriptor E:\WorkSpace\JavaWorkspace\Tomcat 7.0\conf\Catalina\localhost\app1.xml

l  2012-6-3 23:41:23 org.apache.catalina.startup.SetContextPropertiesRule begin

l  警告: [SetContextPropertiesRule]{Context} Setting property 'debug' to '0' did not find a matching property.

l  2012-6-3 23:41:24 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info

l  信息: Parsing configuration file [struts-default.xml]

l  2012-6-3 23:41:24 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info

l  信息: Parsing configuration file [struts-plugin.xml]

l  2012-6-3 23:41:24 com.opensymphony.xwork2.util.logging.commons.CommonsLogger info

l  信息: Parsing configuration file [struts.xml]

5、  删除这个文件后,日志输出:

l  信息: Undeploying context [/app1]

l  2012-6-3 23:43:06 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks

l  严重: The web application [/app1] created a ThreadLocal with key of type [com.opensymphony.xwork2.inject.ContainerImpl$10] (value [com.opensymphony.xwork2.inject.ContainerImpl$10@1f1a3a8]) and a value of type [java.lang.Object[]] (value [[Ljava.lang.Object;@12f9ee1]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.

 

posted on 2012-06-03 23:58  jiangtongcn  阅读(3771)  评论(0编辑  收藏  举报

导航