本文目录:
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
该示例经过设置虚拟主机来提供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 "%r" %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 "%r" %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 "%r" %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
以下图: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。
这两货虽然意义很明确,但"潜规则"很严重。如下面的配置为例。
<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如何提供。有如下几种状况:
<context path="" docBase=webappPATH>
,此时默认context的处理路径为webappPATH。<context path="">
,但却没给定docBase属性,此时该默认context处理路径为appBase/ROOT目录,注意ROOT为大写。path=""
的context时,即host容器中没有明确的path="",此时将隐式定义一个默认context,处理路径为appBase/ROOT目录。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>
tomcat配置文件中配置的是各个组件的属性,全局配置文件为$CATALINA_HOME/conf/server.xml,主要的组件有如下几项:Server,Service,Connector,Engine,Host,Alias,Context,Valve等。配置完配置文件后须要重启tomcat,但在启动后必定要检查tomcat是否启动成功,由于即便出错,不少时候它都不会报错,可从监听端口判断。
配置方法见官方手册,在页面的左边有各个组件的连接。
tomcat的配置文件都是xml文件,如下是xml文件的常见规则:
<?xml version="1.0" encoding="UTF-8"?>
。<!-- XXX -->
,这能够是单行注释,也能够多行注释,只要先后注释符号能对应上,中间的内容都是注释。<!-- 单行定义的方式 -->
<NAME key=value />
<!-- 多行定义的方式 -->
<NAME key=value>
</NAME>
下面个组件的配置中有些地方使用了相对于$CATALINA_BASE的相对路径,它和$CATALINA_HOME小有区别,若是只有一个tomcat实例,则它们是等价的,都是tomcat的安装路径。若是有多个tomcat实例,则$CATALINA_HOME表示的是安装路径,而$CATALINA_BASE表示的是各实例所在根目录。关于tomcat多实例,见running.txt中对应的说明。
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组件。
定义了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。执行器定义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" />
链接器用于接收客户端发送的请求并返回响应给客户端。一个service中能够有多个connector。有多种connector,常见的为http/1.1,http/2和ajp(apache jserv protocol)。在tomcat中,ajp链接协议类型专用于tomcat前端是apache反向代理的状况下。
所以tomcat能够扮演两种角色:
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" />
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实例上。engine是容器中的顶级子容器,其内能够嵌套一个或多个Host做为虚拟主机,且至少一个host要和engine中的默认虚拟主机名称对应。除了host,还能够嵌套releam和valve组件。
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的服务。
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也是由此推断出来的。规则以下:
例如:
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能够提高性能。realm定义的是一个安全上下文,就像是以哪一种方式存储认证时的用户和组相关的数据库。有多种方式能够实现数据存放:
下面是一个常见的使用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" />
Valve中文意思是阀门,相似于过滤器,它能够工做于Engine和Host/Context之间、Host和Context之间以及Context和Web应用程序的某资源之间。一个容器内能够创建多个Valve,并且Valve定义的次序也决定了它们生效的次序。
有多种不一样的Valve:
其中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>
其中相关属性定义有:
另一个经常使用的Valve为AccessLogValve,定义方式大体以下:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
其中prefix和suffix表示日志文件的前缀名称和后缀名称。pattern表示记录日志时的信息和格式。