Tomcat服务器Server.xml详解

在这里插入图片描述

一.server.xml结构

tomcat配置文件中配置的是各个组件的属性,全局配置文件为$CATALINA_HOME/conf/server.xml,主要的组件有以下几项:Server,Service,Connector,Engine,Host,Alias,Context,Valve等。配置完配置文件后需要重启tomcat,但在启动后一定要检查tomcat是否启动成功,因为即使出错,很多时候它都不会报错,可从监听端口判断。

  • tomcat的配置文件都是xml文件,以下是xml文件的常见规则:

**
1.文件第一行设置xml标识,表示该文件是xml格式的文件。例如<?xml version="1.0" encoding="UTF-8"?>
2.xml文件的注释方法为 ,这可以是单行注释,也可以多行注释,只要前后注释符号能对应上,中间的内容都是注释。
3.定义属性时有两种方式:单行定义和多行定义。例如:**

<NAME key=value /><NAME key=value></NAME>
  • Tomcat两个目录的区别和联系

下面个组件的配置中有些地方使用了相对于CATALINA_BASE的相对路径,它和CATALINA_HOME小有区别,如果只有一个tomcat实例,则它们是等价的,都是tomcat的安装路径。如果有多个tomcat实例,则CATALINA_HOME表示的是安装路径,而CATALINA_BASE表示的是各实例所在根目录。关于tomcat多实例,见running.txt中对应的说明。

  • CATALINA_BASE与CATALINA_HOME的区别

到底CATALINA_HOME和CATALINA_BASE有什么区别呢,之前因为都是小打小闹的在服务器上安装一个tomcat就得了,然后根据前人的配置,将CATALINA_HOME和CATALINA_BASE两个值设为了tomcat的目录(其实此处描述很不精确),今天无意间看到了公司的安装文档说明,里面提到了多个tomcat实例运行的配置,才弄明白到底这两者之间有什么区别。
我们可以从Tomcat 5.5的配置文档(http://tomcat.apache.org/tomcat-5.5-doc/config/host.html) 中找到答案:
The description below uses the variable name $CATALINA_HOME to refer to the directory into which you have installed Tomcat 5, and is the base directory against which most relative paths are resolved. However, if you have configured Tomcat 5 for multiple instances by setting a CATALINA_BASE directory, you should use $CATALINA_BASE instead of $CATALINA_HOME for each of these references.
从这段描述可以看出CATALINA_HOME和CATALINA_BASE的区别。简单的说,CATALINA_HOME是Tomcat的安装目 录,CATALINA_BASE是Tomcat的工作目录。如果我们想要运行Tomcat的 多个实例,但是不想安装多个Tomcat软件副本。那么我们可以配置多个工作 目录,每个运行实例独占一个工作目录,但是共享同一个安装目录。
Tomcat每个运行实例需要使用自己的conf、logs、temp、webapps、work和shared目录,因此CATALINA_BASE就 指向这些目录。 而其他目录主要包括了Tomcat的二进制文件和脚本,CATALINA_HOME就指向这些目录。
如果我们希望再运行另一个Tomcat实例,那么我们可以建立一个目录,把conf、logs、temp、webapps、work和shared拷贝 到该目录下,然后让CATALINA_BASE指向该目录即可。
在一台服务器上,可以运行多个tomcat实例,不需要安装多个tomcat,可以采用不同的用户,以test用户为例,拷贝/usr/local/apache-tomcat-6.0.18目录到/home/test下,删除/home/test/apache-tomcat-6.0.18/bin子目录(此目录不需要),编辑/home/test/.bash_profile文件,设置CATALINA_HOME指向刚才的安装目录/usr/local/apache-tomcat-6.0.18,设置JAVA_HOME指向刚才的安装目录/usr/java/jdk1.6.0_11。设置CATALINA_BASE指向/home/test/apache-tomcat-6.0.18,设置CATALINA_OPTS跟/root/.bash_profile的一致(jmx管理端口用不同的端口号)

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.JreMemoryLeakPreventionListener"/>
    <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
    <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
    <!-- 全局命名资源,定义了UserDatabase的一个JNDI(java命名和目录接口),通过pathname的文件得到一个用户授权的内存数据库 -->
    <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元素对应一个web应用,一个这样的web英勇包含一个En-->
    <Service name="Catalina">
        <!--
            每个Service可以有一个或多个连接器<Connector>元素,
            第一个Connector元素定义了一个HTTP Connector,它通过8080端口接收HTTP请求;第二个Connector元素定
            义了一个JD Connector,它通过8009端口接收由其它服务器转发过来的请求.
        -->
        <!--连接器中的port属性是对应-->
        <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443"/>
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
        <!-- 每个Service只能有一个<Engine>元素 -->
        <Engine name="Catalina" defaultHost="localhost">
            <Realm className="org.apache.catalina.realm.LockOutRealm">
                <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                       resourceName="UserDatabase"/>
            </Realm>
            <!-- 默认host配置,有几个域名就配置几个Host,但是这种只能是同一个端口号 -->
            <Host name="localhost" appBase="webapps"
                  unpackWARs="true" autoDeploy="true">
                  <!-- Tomcat的访问日志,默认可以关闭掉它,它会在logs文件里生成localhost_access_log的访问日志 -->
                <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                       prefix="localhost_access_log" suffix=".txt"
                       pattern="%h %l %u %t "%r" %s %b" />
            </Host>
            <Host name="www.hzg.com" appBase="webapps"
                  unpackWARs="true" autoDeploy="true">
                <Context path="" docBase="/myweb1"/>
                <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                       prefix="hzg_access_log" suffix=".txt"
                       pattern="%h %l %u %t "%r" %s %b" />
            </Host>
        </Engine>
    </Service>
</Server>

server.xml元素

Server标签代表一个Tomcat实例,是最外层的标签,是最顶层元素,port属性表示监听的是哪个接口,shutdown属性表示监听的命令听到此命令就关闭该实例,shutdown属性必须设置。
>server相关属性:
•className:用于实现此组件的java类的名称,这个类必须实现接口org.apache.catalina.Server。不给定该属性时将采用默认的标准类org.apache.catalina.core.StandardServer;
•address:监听端口绑定的地址。如不指定,则默认为Localhost,即只能在localhost上发送SHUTDOWN命令;
•port:接收shutdown指令的端口,默认仅允许通过本机访问,默认为8005;
•shutdown:通过TCP/IP连接发往此Server用于实现关闭tomcat实例的命令字符串。
在server组件中可嵌套一个或多个service组件

Service元素

Service元素代表的是一个服务,这个服务的含义就是有这个逻辑组件之后就可以进行对外提供服务了,service服务是由connector和Containor组成,二者组成一个服务

<Service name="Catalina"></Service>

Service相关的属性:
•className:用于实现service的类名,这个类必须实现org.apache.catalina.Service接口。不给定该属性时将采用默认的标准类org.apache.catalina.core.StandardService。
•name:此service的显示名称,该名称主要用于在日志中进行标识service。一般来说无关紧要,默认为Catalina。

在这里插入图片描述

tomcat高度模块化,各个模块之间有嵌套的父子关系。如果使用配置文件来描述,可以大致简化为如下:
<server>
 <service>
  <connector PORT />
  <engine>
   <host name=www.a.com appBase=/www/a >
    <context path="" docBase=/www/a />
    <context path="/xuexi" docBase=/www/a/xuexi />
   </host>
   <host>
    <context .../>
   </host>
  </engine>
 </service>
</server>

执行器executor

执行器定义tomcat各组件之间共享的线程池。在以前,每个connector都会独自创建自己的线程池,但现在,可以定义一个线程池,各组件都可以共享该线程池,不过主要是为各connector之间提供共享。注意,executor创建的是共享线程池,如果某个connector不引用executor创建的线程池,那么该connector仍会根据自己指定的属性创建它们自己的线程池。
连接器必须要实现org.apache.catalina.Executor接口。它是一个嵌套在service组件中的元素,为了挑选所使用的connector,该元素还必须定义在connector元素之前。
默认的定义如下:

<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
  maxThreads="150" minSpareThreads="4"/>

>其中该组件的属性有:
•className:用于实现此组件的java类的名称,这个类必须实现接口org.apache.catalina.Executor。不给定该属性时将采用默认的标准类org.apache.catalina.core.StandardThreadExecutor;
•name:该线程池的名称,其他组件需要使用该名称引用该线程池。
标准类的属性包括:
•threadPriority:线程优先级,默认值为5。
•daemon:线程是否以daemon的方式运行,默认值为true。
•namePrefix:执行器创建每个线程时的名称前缀,最终线程的名称为:namePrefix+threadNumber。
•maxThreads:线程池激活的最大线程数量。默认值为200。
•minSpareThreads:线程池中最少空闲的线程数量。默认值为25。
•maxIdleTime:在空闲线程关闭前的毫秒数。除非激活的线程数量小于或等于minSpareThreads的值,否则会有空闲线程的出现。默认值为60000,即空闲线程需要保留1分钟的空闲时间才被杀掉。
•maxQueueSize:可执行任务的最大队列数,达到队列上限时的连接请求将被拒绝。
•prestartminSpareThreads:在启动executor时是否立即创建minSpareThreads个线程数,默认为false,即在需要时才创建线程。
例如在connector中指定所使用的线程池,方式如下:

<Connector executor="tomcatThreadPool"
      port="8080" protocol="HTTP/1.1"
      connectionTimeout="20000"
      redirectPort="8443" />

Connector组件

连接器用于接收客户端发送的请求并返回响应给客户端。一个service中可以有多个connector。有多种connector,常见的为http/1.1,http/2和ajp(apache jserv protocol)。在tomcat中,ajp连接协议类型专用于tomcat前端是apache反向代理的情况下。
因此tomcat可以扮演两种角色:
1.Tomcat仅作为应用程序服务器:请求来自于前端的web服务器,这可能是Apache, IIS, Nginx等;
2.Tomcat既作为web服务器,也作为应用程序服务器:请求来自于浏览器。
Tomcat应该考虑工作情形并为相应情形下的请求分别定义好需要的连接器才能正确接收来自于客户端的请求。
此处暂先介绍HTTP/1.1连接器的属性设置。ajp后文再做介绍。
HTTP连接器表示支持HTTP/1.1协议的组件。设置了该连接器就表示catalina启用它的独立web服务功能,当然,肯定也提供它必须的servlets和jsp执行功能。在一个service中可以配置一个或多个连接器,每个连接器都可以将请求转发给它们相关联的engine以处理请求、创建响应。
如果想要配置某个web server的连接器,则使用AJP协议。
每个流入的请求都需要一个独立的线程来接收。当并发请求数量超出maxThreads指定的值时,多出的请求将被堆叠在套接字中,直到超出acceptCount指定的值。超出accpetCount的请求将以"connection refused"错误进行拒绝。
默认的定义如下:

<Connector port="8080" protocol="HTTP/1.1"
      connectionTimeout="20000"
      redirectPort="8443" />

HTTP连接器的属性实在太多,详细配置方法见官方手册。通常定义HTTP连接器时必须定义的属性只有"port"。
•address:指定连接器监听的地址,默认为所有地址,即0.0.0.0。
•maxThreads:支持的最大并发连接数,默认为200;如果引用了executor创建的共享线程池,则该属性被忽略。
•acceptCount:设置等待队列的最大长度;通常在tomcat所有处理线程均处于繁忙状态时,新发来的请求将被放置于等待队列中;
•maxConnections:允许建立的最大连接数。acceptCount和maxThreads是接受连接的最大线程数。存在一种情况,maxConnections小于acceptCount时,超出maxConnections的连接请求将被接收,但不会与之建立连接。
•port:监听的端口,默认为0,此时表示随机选一个端口,通常都应该显式指定监听端口。
•protocol:连接器使用的协议,用于处理对应的请求。默认为HTTP/1.1,此时它会自动在基于Java NIO或APR/native连接器之间进行切换。定义AJP协议时通常为AJP/1.3。
•redirectPort:如果某连接器支持的协议是HTTP,当接收客户端发来的HTTPS请求时,则转发至此属性定义的端口。
•connectionTimeout:等待客户端发送请求的超时时间,单位为毫秒,默认为60000,即1分钟;注意,这时候连接已经建立。
•keepAliveTimeout:长连接状态的超时时间。超出该值时,长连接将关闭。
•enableLookups:是否通过request.getRemoteHost()进行DNS查询以获取客户端的主机名;默认为true,应设置为false防止反解客户端主机;
•compression:是否压缩数据。默认为off。设置为on时表示只压缩text文本,设置为force时表示压缩所有内容。应该在压缩和sendfile之间做个权衡。
•useSendfile:该属性为NIO的属性,表示是否启用sendfile的功能。默认为true,启用该属性将会禁止compression属性。
当协议指定为HTTP/1.1时,默认会自动在NIO/APR协议处理方式上进行按需切换,如要显式指定协议,方式如下:

<connector port="8080" protocol="HTTP/1.1">
<connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol">
<connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol">
<connector port="8080" protocol="org.apache.coyote.http11.Http11AprProtocol">
其中NIO是C/C++的非阻塞IO复用模型在JAVA中的IO实现,NIO2即AIO是异步NIO,即异步非阻塞IO:
NioProtocol :non blocking Java NIO connector
Nio2Protocol:non blocking Java NIO2 connector
AprProtocol :the APR/native connector

在这里插入图片描述

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

<Connector port="8443"
  maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
  enableLookups="false" acceptCount="100" debug="0" scheme="https" secure="true"
  clientAuth="false" sslProtocol="TLS" />

Connector组件是服务监听组件,监听外界请求并建立Tcp连接,并将获取到的Tcp链接交由Engine,Cnnector监听到http请求生成request对象和Response对象,并将两个对象交给Engine,并分配线程Engine来进行处理。

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

port:服务端监听的端口号,即客户请求的端口号;
protocol:规定了请求协议;
redirectPort:表示当请求是https时,重定向至端口号为8443的Connector;
connectionTimeout:表示连接的超时时间,单位毫秒;
minSpareThreads:表示Connector最小等待客户请求的线程数,每个请求由一个线程负责,默认10;
maxThreads:表示此连接器要创建的请求处理线程的最大数量,即可以处理的最大并发请求数,默认200;
maxConnections:表示服务器在任何给定时间接受和处理的最大连接数。当达到这个数字时,客户端请求会被放到请求队列,默认最大队列数为acceptCount参数值,BIO模式下默认为maxThreads,NIO模式下默认10000;
acceptCount:maxConnections达到最大值即所有请求线程正在使用时,传入连接请求的最大队列长度, 当队列满时收到的任何请求都将被拒绝, 默认值为100。
maxHeaderCount:允许的请求中的最大header数。 包含比指定限制更多的header的请求将被拒绝。 小于0表示无限制,默认值100。

Container

containor是容器,在配置文件中没有体现出来,它包含4个容器类组件:engine容器、host容器、context容器和wrapper容器。
containor是容器,是Engine元素的逻辑空间,它包含4个容器类组件:engine容器、host容器、context容器和wrapper容器,多个Connector元素共享一个Engine元素。

Engine元素

engine是service组件中用来分析协议的引擎机器,Engine组件在Service组件中有且只有一个,Engine是Service组件中的请求处理组件,它从一个或多个connector上接收请求,并将请求交给对应的虚拟主机进行处理(Engine容器用于从connector组件处接收已建立的TCP连接,还用于接收客户端发送的http请求并分析请求,然后按照分析的结果将相关参数传递给匹配出的虚拟主机),最后返回完整的响应数据给connector,通过connector将响应数据返回给客户端。defaultHost:属性指定了默认的host名称,当发往本机的请求指定的host名称不存在时,一律使用defaultHost指定的host进行处理,因此defaultHost的值,必须与Engine中的一个Host组件的name属性值匹配。engine容器用于从connector组件处接收已建立的TCP连接,还用于接收客户端发送的http请求并分析请求,然后按照分析的结果将相关参数传递给匹配出的虚拟主机。engine还用于指定默认的虚拟主机。

<Engine name="Catalina" defaultHost="localhost">
name:属性用于日志和错误信息,在整个Server中应该唯一。

常用的engine属性有:
•className:实现engine的类,该类必须实现org.apache.catalina.Engine接口。不给定该属性时将采用默认的标准类org.apache.catalina.core.StandardEngine。
•defaultHost:指定处理请求的默认虚拟主机。在Engine中定义的多个虚拟主机的主机名称中至少有一个跟defaultHost定义的主机名称同名。
•name:Engine组件的名称,用于记录日志和错误信息,无关紧要的属性,可随意给定。
•jvmRoute:在启用session粘性时指定使用哪种负载均衡的标识符。所有的tomcat server实例中该标识符必须唯一,它会追加在session标识符的尾部,因此能让前端代理总是将特定的session转发至同一个tomcat实例上。
注意,jvmRoute同样可以使用jvmRoute的系统属性来设置。如果此处设置了jvmRoute,则覆盖jvmRoute系统属性。关于jvmRoute的使用,在后面tomcat ajp负载均衡的文章中介绍。
engine是容器中的顶级子容器,其内可以嵌套一个或多个Host作为虚拟主机,且至少一个host要和engine中的默认虚拟主机名称对应。除了host,还可以嵌套releam和valve组件。

Host元素

host容器定义虚拟主机,由于tomcat主要是作为servlet容器的,所以为每个web应用程序指定了它们的根目录appBase
Engine元素至少包含一个或多个Host元素.每个Host元素定义了一个虚拟主机,它可以包含一个或多个Web应用,其中一个Host的name必须与Engine组件的defaultHost属性相匹配。

<Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true">

name:虚拟主机的名字。
appBase:指定虚拟主机的目录,可以指定绝对目录,也可以指定相对于CATALINA_HOME的相对目录, 如果此项没有设定,默认值为CATALINA_HOME/webapps。
unpackWARs:如果此项设为true,表示将把Web应用的war文件先解压为开放目录结构后再运行.如果设为false,将直接运行war文件。
autoDeploy:如果此项设为true,表示当Tomcat服务器处于运行状态时,能够监测appBase下的文件,如果有新的Web应用加入进来,会自动发布这个Web应用。
另,在Host元素中可以包含如下的子元素: Logger,Realm,Valve,Context。

Context元素

每个Context元素代表了运行在虚拟主机上的单个Web应用,一个Host元素中可以包含多个Context元素。

<Context path="/sample" docBase="sample" debug="0" reloadable="true">   

path:指定访问该Web应用的URL入口。
docBase:指定Web应用的文件路径,可以为绝对路径,也可以为相对于Host的appBase属性的相对路径,如果Web应用采用开放目录结构,那就指定Web应用的根目录;如果Web应用是个WAR文件,那就指定WAR文件的路径。
reloadable:如果这个属性设为true,Tomcat服务器在运行状态下会监视在WEB-INF/class和WEB-INF/lib目录下CLASS文件的改动,如果检测到有calss文件被更新,服务器会自动重新加载Web应用。
三.Tomcat Server处理一个http请求的过程
假设来自客户的请求为:http://localhost:8080/wsota/wsota_index.jsp

  1. 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得;
  2. Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应;
  3. Engine获得请求localhost/wsota/wsota_index.jsp,匹配它所拥有的所有虚拟主机Host;
  4. Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机);
  5. localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有Context;
  6. Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为""的Context去处理);
  7. path="/wsota"的Context获得请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet;
  8. Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类;
  9. 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法;
  10. Context把执行完了之后的HttpServletResponse对象返回给Host;
  11. Host把HttpServletResponse对象返回给Engine;
  12. Engine把HttpServletResponse对象返回给Connector;
  13. Connector把HttpServletResponse对象返回给客户browser;

4.6 容器类host

host容器用来定义虚拟主机。engine从connector接收到请求进行分析后,会将相关的属性参数传递给对应的(筛选方式是从请求首部的host字段和虚拟主机名称进行匹配)虚拟host进行处理。如果没有合适的虚拟主机,则传递给默认虚拟主机。因此每个容器中必须至少定义一个虚拟主机,且必须有一个虚拟主机和engine容器中定义的默认虚拟主机名称相同。

大致定义方式如下:
1
2
3


常用属性说明:

•className:实现host容器的类,该类必须实现org.apache.catalina.Host接口。不给定该属性时将采用默认的标准类org.apache.catalina.core.StandardHost。

•name:虚拟主机的主机名,忽略大小写(初始化时会自动转换为小写)。可以使用前缀星号通配符,如"*.a.com"。使用了星号前缀的虚拟主机的匹配优先级低于精确名称的虚拟主机。

•appBase:此Host的webapps目录,即webapp部署在此虚拟主机上时的存放目录。包括非归档的web应用程序目录和归档后的WAR文件的目录。使用相对路径时基于$CATALINA_BASE。

•xmlBase:部署在此虚拟主机上的context xml目录。

•startStopThreads:启动context容器时的并行线程数。如果使用了自动部署功能,则再次部署或更新时使用相同的线程池。

•autoDeploy:在Tomcat处于运行状态时放置于appBase目录中的应用程序文件是否自动进行deploy或自动更新部署状态。这等于同时开启了deployOnStartup属性和reload/redeploy webapp的功能。触发自动更新时将默认重载该webapp。默认为true。

•unpackWars:在执行此webapps时是否先对归档格式的WAR文件解压再运行,设置为false时则直接执行WAR文件;默认为true。设置为false时会损耗性能。

•workDir:该虚拟主机的工作目录。每个webapp都有自己的临时IO目录,默认该工作目录为$CATALINA_BASE/work。

大多数时候都只需设置虚拟主机名称name和webBase属性即可,其余采用默认,默认时会自动部署webapp。有时候还需要管理多个站点名称,即主机别名。可以使用Alias为Host指定的主机名定义主机别名。如:

1
2
3

www.a.com

自动部署指的是自动装载webapp以提供相关webapp的服务。

4.7 容器类context

connector和containor是整个tomcat的心脏,而context则是containor的心脏,更是tomcat心脏的心脏。它是真正管理servlet的地方,它的配置影响了servlet的工作方式。

一个context代表一个webapp。servlet中规定,每个webapp都必须基于已归档的WAR(WEB application archive)文件或基于非归档相关内容所在目录。

catalina基于对请求URI与context中定义的path进行最大匹配前缀的规则进行挑选,从中选出使用哪个context来处理该HTTP请求。这相当于nginx的location容器,catalina的path就相当于location的path,它们的作用是相同的。

每个context都必须在虚拟主机容器host中有一个唯一的context name。context的path不需要唯一,因为允许同一个webapp不同版本的共存部署。此外,必须要有一个context的path为0长度的字符串(即),该context是该虚拟主机的默认webapp,用于处理所有无法被虚拟主机中所有context path匹配的请求。

关于context name,它是从context path推断出来的,不仅如此,其余几个属性如context basefile name也是由此推断出来的。规则如下:

•如果path不为空,则context name等于context path,basefile name取path中去除前缀"/“后的路径,且所有”/“替换为”#"。

•如果path为空,则context name也为空,而basefile为ROOT(注意是大写)。

例如:

1
2
3
4
5
context path context name basefile name deploy examples

/foo /foo foo foo.xml,foo.war,foo
/foo/bar /foo/bar foo#bar foo#bar.xml,foo#bar.war,foo#bar
Empty String Empty String ROOT ROOT.xml,ROOT.war,ROOT
配置context时,强烈建议不要定义在server.xml中,因为定义conf/server.xml中时,只能通过重启tomcat来重载生效,也就是说无法自动部署应用程序了。虽说官方如此推荐,但大多数人出于习惯和方便,还是会直接写在server.xml中,这并没有什么问题,无非是重启一下而已。

可以考虑定义在/META-INF/context.xml中,如果此时设置了copyXML属性,在部署时会将此context.xml复制到 C A T A L I N A B A S E / c o n f / e n g i n e n a m e / h o s t n a m e / 下,并重命名为 " b a s e f i l e n a m e . x m l " 。也可以直接定义在 CATALINA_BASE/conf/enginename/hostname/下,并重命名为"basefile name.xml"。也可以直接定义在 CATALINABASE/conf/enginename/hostname/下,并重命名为"basefilename.xml"。也可以直接定义在CATALINA_BASE/conf/enginename/hostname/下的.xml文件中,该路径的xml优先级高于/META-INF/context.xml。

还可以定义默认的context.xml文件,包括两种:(1)定义在 C A T A L I N A B A S E / c o n f / c o n t e x t . x m l 中,该默认 c o n t e x t 对所有 w e b a p p 都生效; ( 2 ) 定义在 CATALINA_BASE/conf/context.xml中,该默认context对所有webapp都生效;(2)定义在 CATALINABASE/conf/context.xml中,该默认context对所有webapp都生效;(2)定义在CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default中,该默认context只对该虚拟主机中的所有webapp生效。

定义方式大致如下:

1
2
3
4
5




其中第一个context的path为空字符串,表示它是默认的context。当浏览器中输入www.a.com时,由于无法匹配第二个context,所以被默认即第一个context处理,当浏览器中输入www.a.com/bbs时,将被第二个context处理,它将执行web/bbs所对应的webapp,并返回相关内容。

在context容器中可以定义非常多的属性,详细内容见官方手册,以下是常见的几个属性:

•className:实现host容器的类,该类必须实现org.apache.catalina.Context接口。不给定该属性时将采用默认的标准类org.apache.catalina.core.StandardContext。

•cookies:默认为true,表示启用cookie来标识session。

•docBase:即DocumentRoot,是该webapp的context root,即归档WAR文件所在目录或非归档内容所在目录。可以是绝对路径,也可以是相对于该webapp appBase的相对路径。

•path:定义webapp path。注意,当path=""时,表示默认的context;另外只有在server.xml中才需要定义该属性,其他所有情况下都不能定义该属性,因为会根据docBase和context的xml文件名推断出path。

•reloadable:是否监控/WEB-INF/class和/WEB-INF/lib两个目录中文件的变化,变化时将自动重载。在测试环境下该属性很好,但在真实生产环境部署应用时不应该设置该属性,因为监控会大幅增加负载,因此该属性的默认值为false。

•wrapperClass:实现wrapper容器的类,wrapper用于管理该context中的servlet,该类必须实现org.apache.catalina.Wrapper接口,如果不指定该属性则采用默认的标准类。

•xmlNamespaceAware:和web.xml的解析方式有关。默认为true,设置为false可以提升性能。

•xmlValidation:和web.xml的解析方式有关。默认为true,设置为false可以提升性能。

4.8 被嵌套类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的配置:

1
2

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

1
2
3
4
5
6
7

4.9 被嵌套类valve

Valve中文意思是阀门,类似于过滤器,它可以工作于Engine和Host/Context之间、Host和Context之间以及Context和Web应用程序的某资源之间。一个容器内可以建立多个Valve,而且Valve定义的次序也决定了它们生效的次序。

有多种不同的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:
1
2
3
4



其中相关属性定义有:

•className:在对应位置的后缀上加上".valves.RemoteHostValve"或".valves.RemoteAddrValve";

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

•deny: 以逗号分开的禁止访问的IP地址列表,支持正则;使用方式同allow;仅定义deny项时,非明确deny的地址均被allow;

另外一个常用的Valve为AccessLogValve,定义方式大致如下:

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

其中prefix和suffix表示日志文件的前缀名称和后缀名称。pattern表示记录日志时的信息和格式。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你们出来吧出来吧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值