承接上文http://11107124.blog.51cto.com/11097124/1888311 


server.xml文件时Tomcat的核心配置文件,包括Service,Engine,Realm,Value,Host等组件的相关配置信息。

[root@node1 local]# vim tomcat/conf/server.xml 

<?xml version='1.0' encoding='utf-8'?>

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


  <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" />

<GlobalNamingResources>


 <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>


<Service name="Catalina">

  

  <Connector port="8080" protocol="HTTP/1.1"

               connectionTimeout="20000"

               redirectPort="8443" />

  <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />


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


    <Realm className="org.apache.catalina.realm.LockOutRealm">

     <Realm className="org.apache.catalina.realm.UserDatabaseRealm"

               resourceName="UserDatabase"/>

    </Realm>


  <Host name="localhost"  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 &quot;%r&quot; %s %b" />


      </Host>

    </Engine>

  </Service>

</Server>


server.xml文件中可定义的元素非常多,包括Server, Service, Connector, Engine, Cluster, Host, Alias, Context, Realm, Valve, Manager, Listener, Resources, Resource, ResourceEnvRef, ResourceLink, WatchedResource, GlobalNameingResources, Store,Transaction, Channel, Membership, Transport, Member, ClusterListener等。

下面将一个个详细介绍各个组件

1、Server组件


如上面示例文件中定义的:

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


这会让Tomcat启动一个server实例(Tomcat实例),通常一个JVM只能包含一个Tomcat实例;因此,一台物理服务器上可以在启动多个JVM的情况下在每一个JVM中启动一个Tomcat实例,每个实例分属于一个独立的管理端口,这是一个顶级组件。

如上面示例中,Tomcat实例监听在8005端口以接收shutdown命令,各Server的定义不能使用同一个端口,这意味着如果在同一个物理机上启动了多个Server实例,必须配置它们使用不同的端口。这个端口的定义用于为管理员提供一个关闭此实例的便捷途径,管理员用telnet连接到8005端口执行shutdown就可以把Tomcat关掉,为了安全建议不启用


Server的相关属性:

className: 用于实现此Server容器的完全限定类的名称,默认为                              org.apache.catalina.core.StandardServer;

port: 接收shutdown指令的端口,默认仅允许通过本机访问,默认为8005;

shutdown:发往此Server用于实现关闭tomcat实例的命令字符串,默认为SHUTDOWN; 


2、Service组件:

Service主要用于关联一个引擎和与此引擎相关的连接器,每个连接器通过一个特定的端口和协议(http/ajp)接收入站请求将其转发至关联的引擎进行处理。困此,Service要包含一个引擎(也只能包 含一个引擎)、及一个或多个连接器。


如上面示例中的定义:

<Service name=”Catalina”>


这定义了一个名为Catalina的Service,此名字也会在产生相关的日志信息时记录在日志文件当中。


Service相关的属性:

className: 用于实现service的类名,一般默认都是      org.apache.catalina.core.StandardService。

name:此服务的名称,默认为Catalina;


3、Connector(连接器)组件:

进入Tomcat的请求可以根据Tomcat的工作模式分为如下两类:

(1)Tomcat作为应用程序服务器:请求来自于前端的web服务器转发,这可能是Apache, IIS, Nginx      等;

(2)Tomcat作为独立服务器:请求直接来自于client的web浏览器;


Tomcat应该考虑工作情形并为相应情形下的请求分别定义好需要的连接器才能正确接收来自于客户端的请求。一个引擎可以有一个或多个连接器,以适应多种请求方式。


定义连接器可以使用多种属性,有些属性也只适用于某特定的连接器类型。一般说来,常见于server.xml中的连接器类型通常有4种:

1) HTTP连接器

2) SSL连接器

3) AJP 1.3连接器

4) proxy连接器


如上面示例server.xml中定义的HTTP连接器:

<Connector port="8080" protocol="HTTP/1.1"

      maxThreads="150" connectionTimeout="20000"

      redirectPort="8443"/>

      

定义连接器时可以配置的属性非常多,但通常定义HTTP连接器时必须定义的属性只有“port”,定义AJP连接器时必须定义的属性只有"protocol",因为默认的协议为HTTP。以下为常用属性的说明:

1) address:指定连接器监听的地址,默认为所有地址,即0.0.0.0;

2) maxThreads:支持的最大并发连接数,默认为200;

3) port:监听的端口,默认为0;

4) protocol:连接器使用的协议,默认为HTTP/1.1,定义AJP协议时通常为AJP/1.3;

5) redirectPort:如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,则转发至此属   性定义的端口;

6) connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为60000,即1分钟;

7) enableLookups:是否通过request.getRemoteHost()进行DNS查询以获取客户端的主机名;默认为     true(可以false掉);

8) acceptCount:设置等待队列的最大长度;通常在tomcat所有处理线程均处于繁忙状态时,新发来的   请求将被放置于等待队列中;


下面是一个定义了多个属性的SSL连接器:

<Connector port="8443"

    maxThreads="150" minSpareThreads="25" maxSpareThreads="75"

    enableLookups="false" acceptCount="100" debug="0" scheme="https" secure="true"

    clientAuth="false" sslProtocol="TLS" />


4、Engine组件:

Engine是Servlet处理器的一个实例,即servlet引擎,默认为定义在server.xml中的Catalina。Engine需要defaultHost属性来为其定义一个接收所有发往非明确定义虚拟主机的请求的host组件(因为一个Engine中可以有多个虚拟主机,当用户请求了一个不存在的主机时,这时一般要为引擎指定一个默认的虚拟主机;每一个虚拟主机都可以是一个独立的网站)。

如前面示例中定义的:

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


常用的属性定义:

defaultHost:Tomcat支持基于FQDN(Fully Qualified Domain Name完全合格域名/全称域名)的虚拟主 机,这些虚拟主机可以通过在Engine中定义多个不同的Host组件来实现;但如果此引擎的 连接器收到一个发往非明确定义虚拟主机的请求时则需要将此请求发往一个默认的虚拟主机进行处理,因此,在Engine中定义的多个虚拟主机的主机名称中,至少要有一个虚拟主机的主机名称跟defaultHost定义的主机名称同名;


name:Engine组件的名称,用于日志和错误信息记录时区别不同的引擎;


Engine容器中可以包含Realm、Host、Listener和Valve子容器。


5、Host组件:

位于Engine容器中用于接收和处理请求,如前面示例中的定义:

      <Host name="localhost" appBase="webapps"

        unpackWARs="true" autoDeploy="true"

        xmlValidation="false" xmlNamespaceAware="false">

      </Host>


常用属性说明:

1) appBase:此Host的webapps目录,即存放非归档的web应用程序的目录或归档后的WAR文件的目录路   径;可以使用基于$CATALINA_HOME的相对路径;

2) autoDeploy:在Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy;   默认为true;

3) unpackWars:在启用此webapps时是否对WAR格式的归档文件先进行展开;默认为true;


虚拟主机定义示例:


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

  <Host name="localhost" appBase="webapps">

    <Context path="" docBase="ROOT"/>

    <Context path="/bbs" docBase="/web/bss"

      reloadable="true" crossContext="true"/>

  </Host>

  

  <Host name="mail.zxl.com" appBase="/web/mail">

    <Context path="" docBase="ROOT"/>

  </Host>

</Engine>


主机别名定义:

如果一个主机有两个或两个以上的主机名,额外的名称均可以以别名的形式进行定义,如下:

<Host name="www.zxl.com" appBase="webapps" unpackWARs="true">

  <Alias>zxl.com</Alias>

</Host>


6、Context(上下文)组件:

Context在某些意义上类似于apache中的路径别名,一个Context定义用于标识tomcat实例中的一个Web应用程序。

如下面的定义:

    <!-- Tomcat Root Context -->

    <Context path="" docBase="/web/webapps"/>

    

    <!-- buzzin webapp -->

    <Context path="/bbs"

      docBase="/web/threads/bbs"

      reloadable="true">

    </Context>

    

    <!-- chat server -->

      <Context path="/chat" docBase="/web/chat"/>

      

    <!-- darian web -->

    <Context path="/darian" docBase="darian"/>


在Tomcat中,每一个context定义也可以使用一个单独的XML文件进行,其文件的目录为$CATALINA_HOME/conf/<engine name>/<host name>。可以用于Context中的XML元素有Loader,Manager,Realm,Resources和WatchedResource。


常用的属性定义有:

1) docBase:相应的Web应用程序的存放位置;也可以使用相对路径,起始路径为此Context所属Host中appBase定义的路径;切记,docBase的路径名不能与相应的Host中appBase中定义的路径名有包含关系,比如,如果appBase为deploy,而docBase绝不能为deploy-bbs类的名字;

2) path:相对于Web服务器根路径而言的URI;如果为空“”,则表示为此webapp的根路径;如果context定义在一个单独的xml文件中,此属性不需要定义;

3) reloadable:是否允许重新加载此context相关的Web应用程序的类;默认为false;


7、Realm组件:

用于用户的认证和授权;在配置一个应用程序时,管理员可以为每个资源或资源组定义角色及权限,而这些访问控制功能的生效需要通过Realm来实现;一个Realm表示一个安全上下文,它是一个授权访问某个给定Context的用户列表和某用户所允许切换的角色相关定义的列表。因此,Realm就像是一个用户和组相关的数据库。

定义Realm时惟一必须要提供的属性是classname,它是Realm的多个不同实现,用于表示此Realm认证的用户及角色等认证信息的存放位置。

JAASRealm:基于Java Authintication and Authorization Service实现用户认证;

JDBCRealm:通过JDBC访问某关系型数据库表实现用户认证;

JNDIRealm:基于JNDI使用目录服务实现认证信息的获取;

MemoryRealm:查找tomcat-user.xml文件实现用户信息的获取;

UserDatabaseRealm:基于UserDatabase文件(通常是tomcat-user.xml)实现用户认证,它实现是一个完全可更新和持久有效的MemoryRealm,因此能够跟标准的MemoryRealm兼容;它通过JNDI实现;


下面是一个常见的使用UserDatabase的配置:

  <Realm className=”org.apache.catalina.realm.UserDatabaseRealm”

    resourceName=”UserDatabase”/>


下面是一个使用JDBC方式获取用户认证信息的配置:

  <Realm className="org.apache.catalina.realm.JDBCRealm" debug="99"

    driverName="org.gjt.mm.mysql.Driver"

    connectionURL="jdbc:mysql://localhost/authority"

    connectionName="test" connectionPassword="test"

    userTable="users" userNameCol="user_name"

    userCredCol="user_pass"

    userRoleTable="user_roles" roleNameCol="role_name" />


8、Valve组件:

Valve常被用来记录客户端请求、客户端IP地址和服务器等信息,Valve类似于过滤器,它可以工作于Engine和Host/Context之间、Host和Context之间以及Context和Web应用程序的某资源之间。

一个容器内可以建立多个Valve,而且Valve定义的次序也决定了它们生效的次序。Tomcat中实现了多种不同的Valve:


AccessLogValve:访问日志Valve

ExtendedAccessValve:扩展功能的访问日志Valve

JDBCAccessLogValve:通过JDBC将访问日志信息发送到数据库中;

RequestDumperValve:请求转储Valve;

RemoteAddrValve:基于远程地址的访问控制;

RemoteHostValve:基于远程主机名称的访问控制;

SemaphoreValve:用于控制Tomcat主机上任何容器上的并发访问数量;

JvmRouteBinderValve:在配置多个Tomcat并以Apache通过mod_proxy或mod_jk作为前端的集群架构中,当期望停止某节点时,可以通过此Valve将用求请求定向至备用节点;使用此Valve,必须使用JvmRouteSessionIDBinderListener;

ReplicationValve:专用于Tomcat集群架构中,可以在某个请求的session信息发生更改时触发session数据在各节点间进行复制;

SingleSignOn:将两个或多个需要对用户进行认证webapp在认证用户时连接在一起,即一次认证即可访问所有连接在一起的webapp;

ClusterSingleSingOn:对SingleSignOn的扩展,专用于Tomcat集群当中,需要结合ClusterSingleSignOnListener进行工作;


RemoteHostValve和RemoteAddrValve可以分别用来实现基于主机名称和基于IP地址的访问控制,控制本身可以通过allow或deny来进行定义,这有点类似于Apache的访问控制功能;如下面的Valve则实现了仅允许本机访问/probe:

  <Context path="/probe" docBase="probe">

    <Valve className="org.apache.catalina.valves.RemoteAddrValve"

    allow="127\.0\.0\.1"/>

  </Context>


其中相关属性定义有:

1) className:相关的java实现的类名,相应于分别应该为org.apache.catalina.valves.RemoteHostValve或org.apache.catalina.valves.RemoteAddrValve;

2) allow:以逗号分开的允许访问的IP地址列表,支持正则表达式,因此,点号“.”用于IP地址时需要转义;仅定义allow项时,非明确allow的地址均被deny;

3) deny: 以逗号分开的禁止访问的IP地址列表,支持正则表达式;使用方式同allow;


9、GlobalNamingResources

应用于整个服务器的JNDI映射,此可以避免每个Web应用程序都需要在各自的web.xml创建,这在web应用程序以WAR的形式存在时尤为有用。它通常可以包含三个子元素:

1) Environment;

2) Resource;

3) ResourceEnvRef;


下面是一些不常用的元素定义

10、WatchedResource

WatchedResource可以用于Context中监视指定的webapp程序文件的改变,并且能够在监视到文件内容发生改变时重新装载此文件。


11、Listener

Listener用于创建和配置LifecycleListener对象,而LifecycleListener通常被开发人员用来创建和删除容器。


12、Loader

Java的动态装载功能是其语言功能强大表现之一,Servlet容器使用此功能在运行时动态装载servlet和它们所依赖的类。Loader可以用于Context中控制java类的加载。


13、Manager

Manger对象用于实现HTTP会话管理的功能,Tomcat6中有5种Manger的实现:

1) StandardManager

Tomcat6的默认会话管理器,用于非集群环境中对单个处于运行状态的Tomcat实例会话进行管理。当Tomcat关闭时,这些会话相关的数据会被写入磁盘上的一个名叫SESSION.ser的文件,并在Tomcat下次启动时读取此文件。

2) PersistentManager

当一个会话长时间处于空闲状态时会被写入到swap会话对象,这对于内存资源比较吃紧的应用环境来说比较有用。

3)DeltaManager

用于Tomcat集群的会话管理器,它通过将改变了会话数据同步给集群中的其它节点实现会话复制。这种实现会将所有会话的改变同步给集群中的每一个节点,也是在集群环境中用得最多的一种实现方式。

4) BackupManager

用于Tomcat集群的会话管理器,与DeltaManager不同的是,某节点会话的改变只会同步给集群中的另一个而非所有节点。

5)SimpleTcpReplicationManager

Tomcat4时用到的版本,过于老旧了。


14、Stores

PersistentManager必须包含一个Store元素以指定将会话数据存储至何处。这通常有两种实现方式:FileStore和JDBCStore。


15、Resources

经常用于实现在Context中指定需要装载的但不在Tomcat本地磁盘上的应用资源,如Java类,HTML页面,JSP文件等。


16、Cluster

专用于配置Tomcat集群的元素,可用于Engine和Host容器中。在用于Engine容器中时,Engine中的所有Host均支持集群功能。在Cluster元素中,需要直接定义一个Manager元素,这个Manager元素有一个其值为org.apache.catalina.ha.session.DeltaManager或org.apache.catalina.ha.session.BackupManager的className属性。同时,Cluster中还需要分别定义一个Channel和ClusterListener元素。


(1)Channel

用于Cluster中给集群中同一组中的节点定义通信“信道”。Channel中需要至少定义Membership、Receiver和Sender三个元素,此外还有一个可选元素Interceptor。


(2)Membership

用于Channel中配置同一通信信道上节点集群组中的成员情况,即监控加入当前集群组中的节点并在各节点间传递心跳信息,而且可以在接收不到某成员的心跳信息时将其从集群节点中移除。Tomcat6中Membership的实现是org.apache.catalina.tribes.membership.McastService。


(3)Sender

用于Channel中配置“复制信息”的发送器,实现发送需要同步给其它节点的数据至集群中的其它节点。发送器不需要属性的定义,但可以在其内部定义一个Transport元素。


(4)Transport

用于Sender内部,配置数据如何发送至集群中的其它节点。Tomcat6有两种Transport的实现:

1. PooledMultiSender

基于Java阻塞式IO,可以将一次将多个信息并发发送至其它节点,但一次只能传送给一个节点。

2. PooledParallelSener

基于Java非阻塞式IO,即NIO,可以一次发送多个信息至一个或多个节点。


(5)Receiver

用于Channel定义某节点如何从其它节点的Sender接收复制数据,Tomcat6中实现的接收方式有两种BioReceiver和NioReceiver。