Tomcat配置文件解析

Tomcat作为一个开源的轻量级web容器,使用非常广泛; 其配置文件一般都在 server.xml中配置;

server.xml中的每一个元素都对应tomcat的一个组件,位于 tomcat的conf目录下面

一个完整的 server.xml(tomcat 7)

<?xml version='1.0' encoding='utf-8'?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<!-- Note:  A "Server" is not itself a "Container", so you may not
     define subcomponents such as "Valves" at this level.
     Documentation at /docs/config/server.html
 -->
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <Service name="Catalina">

    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->


    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL HTTP/1.1 Connector on port 8080
    -->
    <Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" 
			  URIencoding= "utf-8"/>
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define a SSL HTTP/1.1 Connector on port 8443
         This connector uses the BIO implementation that requires the JSSE
         style configuration. When using the APR/native implementation, the
         OpenSSL style configuration is required as described in the APR/native
         documentation -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"  URIencoding= "utf-8"/>


    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->

    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="localhost">

      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

     <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false">
			
    <Context path="/gdda45_hdlgdx" docBase="D:\1ZX\svn\gdda45_hdlgdx"  crossContext="true" />
   
		<!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>

整体的结构大致如下

<?xml version='1.0' encoding='utf-8'?>
<Server  >
<Listener className=".." />

    <Service>
        <Connector />
            <Engine>
                 <Host>
                     <Context />
                  </Host>       

            </Engine>
        

    </Service>

</Server>

顶层节点 Server,Service

  Server是整个配置的根元素, 表示一个tomcat容器, 必须是最外部的节点,一个Server可以有一个或多个Service节点

<Server port="8005" shutdown="SHUTDOWN">

port属性表示Server接收shutdown指令的端口号,设为-1可以禁掉该端口。

Server的主要任务,就是提供一个接口让客户端能够访问到这个Service集合,同时维护它所包含的所有的Service的声明周期,包括如何初始化、如何结束服务、如何找到客户端要访问的Service。

<Service>元素则代表一个Engine元素以及一组与之相连的Connector元素。

Service的作用,是在Connector和Engine外面包了一层,把它们组装在一起,对外提供服务。一个Service可以包含多个Connector,但是只能包含一个Engine;其中Connector的作用是从客户端接收请求,Engine的作用是处理接收进来的请求。

连接器节点 : Connector

代表外部发送的请求的配置信息,以及客户端接收的配置信息,即外部客户端发送请求到特定Service的接口;同时也是外部客户端从特定Service接收响应的接口。

Connector的主要功能,是接收连接请求,创建Request和Response对象用于和请求端交换数据;然后分配线程让Engine来处理这个请求,并把产生的Request和Response对象传给Engine。

通过配置Connector,可以控制请求Service的协议及端口号。

 <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000"  redirectPort="8443"  URIencoding= "utf-8"/>

通过配置这个Connector,客户端可以通过80端口号使用http协议访问Tomcat。其中,protocol属性规定了请求的协议,port规定了请求的端口号,redirectPort表示当强制要求https而请求是http时,重定向至端口号为8443的Connector,connectionTimeout表示连接的超时时间,URIencoding= "utf-8" 设置编码格式。

 <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"  URIencoding= "utf-8"/>

通过配置这个Connector,客户端可以通过8009端口号使用AJP协议访问Tomcat。AJP协议负责和其他的HTTP服务器(如Apache)建立连接;在把Tomcat与其他HTTP服务器集成时,就需要用到这个连接器。之所以使用Tomcat和其他服务器集成,是因为Tomcat可以用作Servlet/JSP容器,但是对静态资源的处理速度较慢,不如Apache和IIS等HTTP服务器;因此常常将Tomcat与Apache等集成,前者作Servlet容器,后者处理静态资源,而AJP协议便负责Tomcat和Apache的连接

容器 Engine,Host,Context

容器能够对连接器接接收的请求进行接收并处理,  Engine,Host,Context 都是容器,他们是父子的关系,一个Engine组件可以处理Service中的所有请求,一个Host组件可以处理发向一个特定虚拟主机的所有请求,一个Context组件可以处理一个特定Web应用的所有请求。

Engine

Engine组件在Service组件中有且只有一个;Engine是Service组件中的请求处理组件。Engine组件从一个或多个Connector中接收请求并处理,并将完成的响应返回给Connector,最终传递给客户端。

 <Engine name="Catalina" defaultHost="localhost">

name属性用于日志和错误信息,在整个Server中应该唯一。defaultHost属性指定了默认的host名称,当发往本机的请求指定的host名称不存在时,一律使用defaultHost指定的host进行处理;因此,defaultHost的值,必须与Engine中的一个Host组件的name属性值匹配。

Host

Host是Engine的子容器。Engine组件中可以内嵌1个或多个Host组件,每个Host组件代表Engine中的一个虚拟主机。Host组件至少有一个,且其中一个的name必须与Engine组件的defaultHost属性相匹配。

Host虚拟主机的作用,是运行多个Web应用(一个Context代表一个Web应用),并负责安装、展开、启动和结束每个Web应用。

Host组件代表的虚拟主机,对应了服务器中一个网络名实体(如”www.test.com”,或IP地址”116.25.25.25”);为了使用户可以通过网络名连接Tomcat服务器,这个名字应该在DNS服务器上注册。

客户端通常使用主机名来标识它们希望连接的服务器;该主机名也会包含在HTTP请求头中。Tomcat从HTTP头中提取出主机名,寻找名称匹配的主机。如果没有匹配,请求将发送至默认主机。因此默认主机不需要是在DNS服务器中注册的网络名,因为任何与所有Host名称不匹配的请求,都会路由至默认主机。

 <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false">

name属性指定虚拟主机的主机名,一个Engine中有且仅有一个Host组件的name属性与Engine组件的defaultHost属性相匹配;一般情况下,主机名需要是在DNS服务器中注册的网络名,但是Engine指定的defaultHost不需要,原因在前面已经说明。

unpackWARs指定了是否将代表Web应用的WAR文件解压;如果为true,通过解压后的文件结构运行该Web应用,如果为false,直接使用WAR文件运行Web应用。

Host的autoDeploy和appBase属性,与Host内Web应用的自动部署有关;此外,本例中没有出现的xmlBase和deployOnStartup属性,也与Web应用的自动部署有关;

Context

(1)Context的作用

Context元素代表在特定虚拟主机上运行的一个Web应用。每个Web应用基于WAR文件,或WAR文件解压后对应的目录

Context是Host的子容器,每个Host中可以定义任意多的Context元素。

 <Context path="/gdda45_hdlgdx" docBase="D:\1ZX\svn\gdda45_hdlgdx"  crossContext="true" />
   

(2)Web应用自动部署

Host的配置

要开启Web应用的自动部署,需要配置所在的虚拟主机;配置的方式就是前面提到的Host元素的deployOnStartup和autoDeploy属性。如果deployOnStartup和autoDeploy设置为true,则tomcat启动自动部署:当检测到新的Web应用或Web应用的更新时,会触发应用的部署(或重新部署)。二者的主要区别在于,deployOnStartup为true时,Tomcat在启动时检查Web应用,且检测到的所有Web应用视作新应用;autoDeploy为true时,Tomcat在运行时定期检查新的Web应用或Web应用的更新。除此之外,二者的处理相似。

通过配置deployOnStartup和autoDeploy可以开启虚拟主机自动部署Web应用;实际上,自动部署依赖于检查是否有新的或更改过的Web应用,而Host元素的appBase和xmlBase设置了检查Web应用更新的目录。

其中,appBase属性指定Web应用所在的目录,默认值是webapps,这是一个相对路径,代表Tomcat根目录下webapps文件夹。

xmlBase属性指定Web应用的XML配置文件所在的目录,默认值为conf/<engine_name>/<host_name>

检查Web应用更新

一个Web应用可能包括以下文件:XML配置文件,WAR包,以及一个应用目录(该目录包含Web应用的文件结构);其中XML配置文件位于xmlBase指定的目录,WAR包和应用目录位于appBase指定的目录。

Tomcat按照如下的顺序进行扫描,来检查应用更新:

A、扫描虚拟主机指定的xmlBase下的XML配置文件

B、扫描虚拟主机指定的appBase下的WAR文件

C、扫描虚拟主机指定的appBase下的应用目录

<Context>元素的配置

Context元素最重要的属性是docBase和path,此外reloadable属性也比较常用。

docBase指定了该Web应用使用的WAR包路径,或应用目录。需要注意的是,在自动部署场景下(配置文件位于xmlBase中),docBase不在appBase目录中,才需要指定;如果docBase指定的WAR包或应用目录就在docBase中,则不需要指定,因为Tomcat会自动扫描appBase中的WAR包和应用目录,指定了反而会造成问题。

path指定了访问该Web应用的上下文路径,当请求到来时,Tomcat根据Web应用的 path属性与URI的匹配程度来选择Web应用处理相应请求。例如,Web应用app1的path属性是”/app1”,Web应用app2的path属性是”/app2”,那么请求/app1/index.html会交由app1来处理;而请求/app2/index.html会交由app2来处理。如果一个Context元素的path属性为””,那么这个Context是虚拟主机的默认Web应用;当请求的uri与所有的path都不匹配时,使用该默认Web应用来处理。但是,需要注意的是,在自动部署场景下(配置文件位于xmlBase中),不能指定path属性,path属性由配置文件的文件名、WAR文件的文件名或应用目录的名称自动推导出来。如扫描Web应用时,发现了xmlBase目录下的app1.xml,或appBase目录下的app1.WAR或app1应用目录,则该Web应用的path属性是”app1”。如果名称不是app1而是ROOT,则该Web应用是虚拟主机默认的Web应用,此时path属性推导为””。

reloadable属性指示tomcat是否在运行时监控在WEB-INF/classes和WEB-INF/lib目录下class文件的改动。如果值为true,那么当class文件改动时,会触发Web应用的重新加载。在开发环境下,reloadable设置为true便于调试;但是在生产环境中设置为true会给服务器带来性能压力,因此reloadable参数的默认值为false。

 <Context path="/gdda45_hdlgdx" docBase="D:\1ZX\svn\gdda45_hdlgdx"  crossContext="true"  reloadable="true" />

在开发环境下,设置reloadable设置为true,便于开发调试。

最典型的自动部署,就是当我们安装完Tomcat后,webapps目录下有如下文件夹:

当我们启动Tomcat后,可以使用http://localhost:8080/来访问Tomcat,其实访问的就是ROOT对应的Web应用;我们也可以通过http://localhost:8080/docs来访问docs应用,同理我们可以访问examples/host-manager/manager这几个Web应用。

(3)server.xml中静态部署Web应用

除了自动部署,我们也可以在server.xml中通过<context>元素静态部署Web应用。静态部署与自动部署是可以共存的。在实际应用中,并不推荐使用静态部署,因为server.xml 是不可动态重加载的资源,服务器一旦启动了以后,要修改这个文件,就得重启服务器才能重新加载。而自动部署可以在Tomcat运行时通过定期的扫描来实现,不需要重启服务器。

server.xml中使用Context元素配置Web应用,Context元素应该位于Host元素中。

 <Context path="/gdda45_hdlgdx" docBase="D:\1ZX\svn\gdda45_hdlgdx"  crossContext="true"  reloadable="true" />

docBase:静态部署时,docBase可以在appBase目录下,也可以不在;本例中,docBase不在appBase目录下。

path:静态部署时,可以显式指定path属性,但是仍然受到了严格的限制:只有当自动部署完全关闭(deployOnStartup和autoDeploy都为false)或docBase不在appBase中时,才可以设置path属性。在本例中,docBase不在appBase中,因此path属性可以设置。

reloadable属性的用法与自动部署时相同。

Listener

  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <Listener className="org.apache.catalina.core.JasperListener" />
   <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

Listener(即监听器)定义的组件,可以在特定事件发生时执行特定的操作;被监听的事件通常是Tomcat的启动和停止。

监听器可以在Server、Engine、Host或Context中,本例中的监听器都是在Server中。实际上,本例中定义的6个监听器,都只能存在于Server组件中。监听器不允许内嵌其他组件。

监听器需要配置的最重要的属性是className,该属性规定了监听器的具体实现类,该类必须实现了org.apache.catalina.LifecycleListener接口。

下面依次介绍例子中配置的监听器:

  • VersionLoggerListener:当Tomcat启动时,该监听器记录Tomcat、Java和操作系统的信息。该监听器必须是配置的第一个监听器。
  • AprLifecycleListener:Tomcat启动时,检查APR库,如果存在则加载。APR,即Apache Portable Runtime,是Apache可移植运行库,可以实现高可扩展性、高性能,以及与本地服务器技术更好的集成。 对应的是 bin/tcnative-1.dll ,
  • JasperListener:在Web应用启动之前初始化Jasper,Jasper是JSP引擎,把JVM不认识的JSP文件解析成java文件,然后编译成class文件供JVM使用。
  • JreMemoryLeakPreventionListener:与类加载器导致的内存泄露有关。
  • GlobalResourcesLifecycleListener:通过该监听器,初始化< GlobalNamingResources>标签中定义的全局JNDI资源;如果没有该监听器,任何全局资源都不能使用。< GlobalNamingResources>将在后文介绍。
  • ThreadLocalLeakPreventionListener:当Web应用因thread-local导致的内存泄露而要停止时,该监听器会触发线程池中线程的更新。当线程执行完任务被收回线程池时,活跃线程会一个一个的更新。只有当Web应用(即Context元素)的renewThreadsWhenStoppingContext属性设置为true时,该监听器才有效。

GlobalNamingResources

  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

GlobalNamingResources元素定义了全局资源,通过配置可以看出,该配置是通过读取 conf/tomcat-users.xml实现的。

核心组件的关系

Server元素在最顶层,代表整个Tomcat容器;一个Server元素中可以有一个或多个Service元素。

Service在Connector和Engine外面包了一层,把它们组装在一起,对外提供服务。一个Service可以包含多个Connector,但是只能包含一个Engine;Connector接收请求,Engine处理请求。

Engine、Host和Context都是容器,且 Engine包含Host,Host包含Context。每个Host组件代表Engine中的一个虚拟主机;每个Context组件代表在特定Host上运行的一个Web应用。

请求处理

当请求被发送到Tomcat所在的主机时,如何确定最终哪个Web应用来处理该请求呢?

(1)根据协议和端口号选定Service和Engine

Service中的Connector组件可以接收特定端口的请求,因此,当Tomcat启动时,Service组件就会监听特定的端口。在第一部分的例子中,Catalina这个Service监听了8080端口(基于HTTP协议)和8009端口(基于AJP协议)。当请求进来时,Tomcat便可以根据协议和端口号选定处理请求的Service;Service一旦选定,Engine也就确定。

通过在Server中配置多个Service,可以实现通过不同的端口号来访问同一台机器上部署的不同应用。

(2)根据域名或IP地址选定Host

Service确定后,Tomcat在Service中寻找名称与域名/IP地址匹配的Host处理该请求。如果没有找到,则使用Engine中指定的defaultHost来处理该请求。在第一部分的例子中,由于只有一个Host(name属性为localhost),因此该Service/Engine的所有请求都交给该Host处理。

(3)根据URI选定Context/Web应用

这一点在Context一节有详细的说明:Tomcat根据应用的 path属性与URI的匹配程度来选择Web应用处理相应请求,这里不再赘述。

(4)举例

以请求http://localhost:80/gdda45_hdlgdx/index.html为例,首先通过协议和端口号(http和8080)选定Service;然后通过主机名(localhost)选定Host;然后通过uri(/gdda45_hdlgdx/index.html)选定Web应用。

猜你喜欢

转载自blog.csdn.net/aa15237104245/article/details/83537131