tomcat配置文件server.xml详解

本文目录:
1. 入门示例:虚拟主机提供web服务
2. tomcat体系结构基本说明
3. tomcat的appBase和docBase详细说明
4. tomcat进阶:tomcat配置文件server.xml详解
 4.1 顶级元素server
 4.2 顶级元素service
 4.3 执行器executor
 4.4 链接器connector
 4.5 容器类engine
 4.6 容器类host
 4.7 容器类context
 4.8 被嵌套类realm
 4.9 被嵌套类valve javascript

1. 入门示例:虚拟主机提供web服务

该示例经过设置虚拟主机来提供web服务,由于是入门示例,因此设置极其简单,只需修改$CATALINA_HOME/conf/server.xml文件为以下内容便可。其中大部分都采用了默认设置,只是在engine容器中添加了两个Host容器。php

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

  <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" enableLookups="false" />
    <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容器做为虚拟主机 -->
      <Host name="www.longshuai.com" appBase="/www/webapps/longshuai" unpackWARs="true" autoDeploy="true">
          <Context path="" docBase="/www/webapps/longshuai" reloadable="true" />
          <Context path="/xuexi" docBase="xuexi" reloadable="true" />
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="longshuai_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
      <Host name="www.xiaofang.com" appBase="/www/webapps/xiaofang" unpackWARs="true" autoDeploy="true">
          <Context path="" docBase="/www/webapps/xiaofang" reloadable="true" />
          <Context path="/xuexi" docBase="xuexi" reloadable="true" />
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="xiaofang_access_log" suffix=".txt" pattern="%h %l %u %t &quot;%r&quot; %s %b" />
      </Host>
      <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>

除了engine中定义的默认localhost虚拟主机,另外布置了两个虚拟主机www.longshuai.com和www.xiaofang.com,它们的程序目录分别为/www/longshuai和/www/xiaofang,因此须要提早创建好这两个目录。另外,在context中定义了docBase,对于uri路径/xuexi,它的文件系统路径为/www/{longshuai,xiaofang}/xuexi目录,因此也要在上面两个程序根目录中定义好xuexi目录。除此以外,还分别为这3个虚拟主机定义了日志,它们的路径为相对路径logs,相对于$CATALINA_HOME。css

再提供appBase目录和docBase目录。html

mkdir -p /www/{longshuai,xiaofang}/xuexi

再提供测试用的index.jsp文件。内容大体以下,分别复制到/www/{longshuai,xiaofang}/和/www/{longshuai,xiaofang}/xuexi/下,并将out.println的输出内容分别稍做修改,使可以区分读取的是哪一个index.jsp。前端

<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
  <body>
    <% out.println("hello world from longshuai Root"); %>
  </body>
</html>

最后重启catalina。java

catalina.sh stop catalina.sh start

再测试主机上添加www.{longshuai,xiaofang}.com的host记录。例如在windows上,在C:\Windows\System32\drivers\etc\hosts中添加以下记录:mysql

192.168.100.22 www.longshuai.com www.xiaofang.com

在浏览器中进行测试,结果以下:nginx

2. tomcat体系结构基本说明

以下图:git

tomcat高度模块化,各个模块之间有嵌套的父子关系。若是使用配置文件来描述,能够大体简化为以下:github

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

其中server组件是工做在后台管理tomcat实例的组件,能够监听一个端口,今后端口上能够远程向该实例发送shutdown关闭命令。
service组件是一个逻辑组件,绑定connector和containor,有了service表示能够向外提供服务,就像是通常的daemon类服务的service。
connector组件是服务监听组件,用于监听外界请求并创建TCP链接,而后将链接交给containor,以后能够今后链接传输数据,例如接收http请求,发送http响应等。
containor是容器,在配置文件中没有体现出来,它包含4个容器类组件:engine容器、host容器、context容器和wrapper容器。
engine容器用于从connector组件处接收已创建的TCP链接,还用于接收客户端发送的http请求并分析请求,而后按照分析的结果将相关参数传递给匹配出的虚拟主机。engine还用于指定默认的虚拟主机。
host容器定义虚拟主机,因为tomcat主要是做为servlet容器的,因此为每一个web应用程序指定了它们的根目录appBase。
context容器对应servlet容器的处理过程。还能够指定相关的wrapper容器类,固然通常都采用默认的标准wrapper类。

最后当请求处理完毕后,context将响应数据返回给host,再返回给engine,再返回给connector,最后返回给客户端。

撇开tomcat做为servlet容器的行为。它和apache、nginx的功能大体都能对应上。例如以nginx为例,如下是nginx提供web服务时的配置结构:

server {
    listen PORT;
    server_name www.a.com;   # 对应于<host name=www.a.com>
    location / {             # 对应于context path=""
            root   html;     # 对应于docBase
        }
    location /xuexi {        # 对应于context path="/xuexi"
            root   html/xuexi;
        }
}

connetcor组件相似于nginx的listen指令。host容器相似于nginx的server指令,host容器中的name属性至关于nginx的server_name指令。engine组件则没有对应配置项,不过在nginx一样有engine的功能,例如默认的虚拟主机,分析URL来判断请求交给哪一个虚拟主机处理等。context容器至关于location指令,context容器的path属性至关于location的uri匹配路径,docBase至关于location的中的root指令,即DocumentRoot。

tomcat做为简单的web服务程序大体如此,但它的核心毕竟是处理servlet和jsp,它必须得管理好每一个webapp。所以,对于tomcat来讲,必需要掌握部署webapp的方式。在tomcat上部署webapp时,必需要理解context的概念,对于tomcat而言,每一个context都应该算是一个webapp,其路径由docBase决定,该目录存放的是归档的war文件或未归档的webapp相关文件,而host容器中的appBase则是虚拟主机整理webapp的地方,一个appBase下能够有多个webapp,即多个context

3. tomcat的appBase和docBase详细说明

这两货虽然意义很明确,但"潜规则"很严重。如下面的配置为例。

<host name=www.a.com appBase=/www/a >
    <context path="" docBase=/www/a />
    <context path="/xuexi" docBase=/www/a/xuexi />
</host>

appBase是虚拟主机存放webapp的目录,它能够是相对路径,也能够是绝对路径。若是是相对路径,则相对于$CATALINA_HOME,严格地说是$CATALINA_BASE。

path是URI的匹配路径,至关于nginx的location后的路径。tomcat要求每一个虚拟主机必须配置一个空字符串的path,该条context做为URI没法被明确匹配时的默认context,它至关于nginx中location / {}的做用。

docBase则是每一个webapp的存放目录(或者是已归档的war文件),它能够是相对路径,也能够是绝对路径,提供相对路径时它相对于appBase。该目录通常在appBase的目录下,但并不规定必定要放在appBase下。对于web服务来讲,它至关于nginx的root指令,但对于webapp来讲,一个context就至关于一个webapp,而docBase正是webapp的路径。

"潜规则"在于默认的context如何提供。有如下几种状况:

  1. 明肯定义了<context path="" docBase=webappPATH>,此时默认context的处理路径为webappPATH。
  2. 明肯定义了<context path="">,但却没给定docBase属性,此时该默认context处理路径为appBase/ROOT目录,注意ROOT为大写。
  3. 彻底没有定义path=""的context时,即host容器中没有明确的path="",此时将隐式定义一个默认context,处理路径为appBase/ROOT目录。
  4. 定义了path但没有定义docBase属性时,docBase将根据path推断出它的路径。推断的规则以下:
context path    context name    推断出的docBase路径
--------------------------------------------------
/foo /foo            foo    
/foo/bar        /foo/bar        foo/bar
Empty String    Empty String    ROOT

如下是几个定义示例:

# 虚拟主机中没有定义任何context,将以appBase下的ROOT做为默认处理路径
<Host appBase="webapps">
</Host>

# 没有定义path=""的context,但定义了path非空的context,也将以ROOT做为默认处理路径
# 若是下面的Context容器中省略docBase属性,则推断出其docBase路径为appBase/xuexi
<Host appBase="webapps">
    <Context path="/xuexi" docBase="webappPATH" />
</Host>

# 某个context定义了path="",该context将做为默认context
# 但该默认context没有定义docBase,将推断出其docBase路径为appBase/ROOT
<Host appBase="webapps">
    <Context path="" docBase="webappPATH" />
</Host>

# 某个context定义了path="",该context将做为默认context
# 下面的默认context明肯定义了docBase
<Host appBase="webapps">
    <Context path="" docBase="webappPATH" />
</Host>

4. tomcat配置文件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文件的注释方法为<!-- XXX -->,这能够是单行注释,也能够多行注释,只要先后注释符号能对应上,中间的内容都是注释。
  3. 定义属性时有两种方式:单行定义和多行定义。例如:
<!-- 单行定义的方式 -->
<NAME key=value />

<!-- 多行定义的方式 -->
<NAME key=value>
</NAME>

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

4.1 顶级元素server

server组件定义的是一个tomcat实例。默认定义以下:

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

它默认监听在8005端口以接收shutdown命令。要启用多个tomcat实例,将它们监听在不一样的端口便可。这个端口的定义为管理员提供一个关闭实例的便捷途径,能够直接telnet至此端口使用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组件。

4.2 顶级元素service

定义了service就能提供服务了。service组件中封装connector和containor,它同时也表示将此service中的connector和containor绑定起来,即由它们组成一个service向外提供服务。默认定义以下:

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

Service相关的属性:

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

4.3 执行器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" />

4.4 链接器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
它们之间的异同点以下表所示:

  Java Nio Connector Java Nio2 Connector APR/native Connector
Classname Http11NioProtocol Http11Nio2Protocol Http11AprProtocol
Tomcat Version 6.x onwards 8.x onwards 5.5.x onwards
Support Polling YES YES YES
Polling Size maxConnections maxConnections maxConnections
Read Request Headers Non Blocking Non Blocking Non Blocking
Read Request Body Blocking Blocking Blocking
Write Response Headers and Body Blocking Blocking Blocking
Wait for next Request Non Blocking Non Blocking Non Blocking
SSL Support Java SSL or OpenSSL Java SSL or OpenSSL OpenSSL
SSL Handshake Non blocking Non blocking Blocking
Max Connections maxConnections maxConnections maxConnections

下面是一个定义了多个属性的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.5 容器类engine

engine是service组件中用来分析协议的引擎机器,它从一个或多个connector上接收请求,并将请求交给对应的虚拟主机进行处理,最后返回完整的响应数据给connector,经过connector将响应数据返回给客户端。

只有一个engine元素必须嵌套在每一个service中,且engine必须在其所须要关联的connector以后,这样在engine前面的connector均可以被此engine关联,而在engine后面的connector则被忽略,由于一个service中只容许有一个engine。

定义方式大体以下:

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

<Engine name="Standalone" defaultHost="localhost" jvmRoute="TomcatA">
</Engine>

经常使用的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组件。

4.6 容器类host

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

大体定义方式以下:

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

经常使用属性说明:

  • 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指定的主机名定义主机别名。如:

<Host name="web.a.com" appBase="webapps" unpackWARs="true">
  <Alias>www.a.com</Alias>
</Host>

自动部署指的是自动装载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 path="" docBase="ROOT"/>),该context是该虚拟主机的默认webapp,用于处理全部没法被虚拟主机中全部context path匹配的请求。

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

  • 若是path不为空,则context name等于context path,basefile name取path中去除前缀"/"后的路径,且全部"/"替换为"#"。
  • 若是path为空,则context name也为空,而basefile为ROOT(注意是大写)。

例如:

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复制到$CATALINA_BASE/conf/enginename/hostname/下,并重命名为"basefile name.xml"。也能够直接定义在$CATALINA_BASE/conf/enginename/hostname/下的.xml文件中,该路径的xml优先级高于/META-INF/context.xml。

还能够定义默认的context.xml文件,包括两种:(1)定义在$CATALINA_BASE/conf/context.xml中,该默认context对全部webapp都生效;(2)定义在$CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default中,该默认context只对该虚拟主机中的全部webapp生效。

定义方式大体以下:

<Host name="www.a.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
      <Context path="" docBase="ROOT"/>
      <Context path="/bbs" docBase="web/bbs" reloadable="true"/>
</Host>

其中第一个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的配置:

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

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:

<Context privileged="true" path="/probe" docBase="probe">
  <Valve className="org.apache.catalina.valves.RemoteAddrValve" allow="127\.0\.0\.1"/>
</Context>

其中相关属性定义有:

  • 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表示记录日志时的信息和格式。

回到Linux系列文章大纲:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

回到网站架构系列文章大纲:http://www.cnblogs.com/f-ck-need-u/p/7576137.html

回到数据库系列文章大纲:http://www.cnblogs.com/f-ck-need-u/p/7586194.html

转载请注明出处:http://www.cnblogs.com/f-ck-need-u/p/7727256.html

注:若您以为这篇文章还不错请点击右下角推荐,您的支持能激发做者更大的写做热情,很是感谢!

相关文章
相关标签/搜索