tomcat配置⽂件l详解
1. ⼊门⽰例:虚拟主机提供web服务
该⽰例通过设置虚拟主机来提供web服务,因为是⼊门⽰例,所以设置极其简单,只需修改$CATALINA_HOME/l⽂件为如下内容即可。其中⼤部分都采⽤了默认设置,只是在engine容器中添加了两个Host容器。
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005"shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.AprLifecycleListener"SSLEngine="on" />
<Listener className="org.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.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="l" />
</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.alm.LockOutRealm">
<Realm className="org.alm.UserDatabaseRealm"
resourceName="UserDatabase" />
</Realm>
<!-- 从此处开始添加以下两个Host容器作为虚拟主机 -->
<Host name="www.longshuai"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"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和www.xiaofang,它们的程序⽬录分别为/www/longshuai
和/www/xiaofang,所以需要提前建⽴好这两个⽬录。另外,在context中定义了docBase,对于uri路径/xuexi,它的⽂件系统路径
为/www/{longshuai,xiaofang}/xuexi⽬录,所以也要在上⾯两个程序根⽬录中定义好xuexi⽬录。除此之外,还分别为这3个虚拟主机定义了⽇志,它们的路径为相对路径logs,相对于$CATALINA_HOME。
再提供appBase⽬录和docBase⽬录。
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。
catalina.sh stop
catalina.sh start
再测试主机上添加www.{longshuai,xiaofang}的host记录。例如在windows上,在C:\Windows\System32\drivers\etc\hosts中添加如下记录:
192.168.100.22 www.longshuai www.xiaofang
在浏览器中进⾏测试,结果如下:
2. tomcat体系结构基本说明
如下图:
tomcat⾼度模块化,各个模块之间有嵌套的⽗⼦关系。如果使⽤配置⽂件来描述,可以⼤致简化为如下:
<server>
<service>
<connector PORT />
<engine>
<host name=www.a 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; # 对应于<host name=www.a>
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 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⽬录。
定义了path但没有定义docBase属性时,docBase将根据path推断出它的路径。推断的规则如下:
context path context name 推断出的docBase路径
--------------------------------------------------
servlet和tomcat的关系/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配置⽂件l详解
tomcat配置⽂件中配置的是各个组件的属性,全局配置⽂件为$CATALINA_HOME/l,主要的组件有以下⼏项:
Server,Service,Connector,Engine,Host,Alias,Context,Valve等。配置完配置⽂件后需要重启tomcat,但在启动后⼀定要检查tomcat是否启动成功,因为即使出错,很多时候它都不会报错,可从监听端⼝判断。
配置⽅法见,在页⾯的左边有各个组件的链接。
tomcat的配置⽂件都是xml⽂件,以下是xml⽂件的常见规则:
⽂件第⼀⾏设置xml标识,表⽰该⽂件是xml格式的⽂件。例如<?xml version="1.0" encoding="UTF-8"?>。
xml⽂件的注释⽅法为<!-- XXX -->,这可以是单⾏注释,也可以多⾏注释,只要前后注释符号能对应上,中间的内容都是注释。
定义属性时有两种⽅式:单⾏定义和多⾏定义。例如:
<!-- 单⾏定义的⽅式 -->
<NAME key=value />
<!-- 多⾏定义的⽅式 -->
<NAME key=value>
</NAME>
下⾯个组件的配置中有些地⽅使⽤了相对于$CATALINA_BASE的相对路径,它和$CATALINA_HOME⼩有区别,如果只有⼀个tomcat实例,则它们是等价的,都是tomcat的安装路径。如果有多个tomcat实例,则$CATALINA_HOME表⽰的是安装路径,⽽$CATALINA_BASE表⽰的是各实例所在根⽬录。关于tomcat多实例,见中对应的说明。
4.1 顶级元素server
server组件定义的是⼀个tomcat实例。默认定义如下:
<Server port="8005"shutdown="SHUTDOWN">
</Server>
它默认监听在8005端⼝以接收shutdown命令。要启⽤多个tomcat实例,将它们监听在不同的端⼝即可。这个端⼝的定义为管理员提供⼀个关闭实例的便捷途径,可以直接telnet⾄此端⼝使⽤SHUTDOWN命令关闭此实例。不过基于安全⾓度的考虑,通常不允许远程进⾏。
Server的相关属性:
className:⽤于实现此组件的java类的名称,这个类必须实现接⼝org.apache.catalina.Server。不给定该属性时将采⽤默认的标准类
org.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.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.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可以扮演两种⾓⾊:
Tomcat仅作为应⽤程序服务器:请求来⾃于前端的web服务器,这可能是Apache, IIS, Nginx等;
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:是否通过RemoteHost()进⾏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="http11.Http11NioProtocol">
<connector port="8080"protocol="http11.Http11Nio2Protocol">
<connector port="8080"protocol="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 ConnectorAPR/native Connector
Classname Http11NioProtocol Http11Nio2Protocol Http11AprProtocol
Tomcat Version 6.x onwards8.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 BodyBlocking Blocking Blocking
Wait for next Request Non Blocking Non Blocking Non Blocking
SSL Support Java SSL or OpenSSLJava SSL or OpenSSLOpenSSL
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.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.StandardHost。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论