基于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"
servlet和tomcat的关系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.xia
ofang,它们的程序⽬录分别为/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如何提供。有以下⼏种情况:
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配置⽂件l详解
tomcat配置⽂件中配置的是各个组件的属性,全局配置⽂件为$CATALINA_HOME/l,主要的组件有以下⼏项:Server,Service,Connector,Engine,Host,Alias,Context,Valve等。配置完配置⽂件后需要重启tomcat,但在启动后⼀定要检查tomcat是否启动成功,因为即使出错,很多时候它都不会报错,可从监听端⼝判断。
配置⽅法见官⽅⼿册,在页⾯的左边有各个组件的链接。
tomcat的配置⽂件都是xml⽂件,以下是xml⽂件的常见规则:
1.⽂件第⼀⾏设置xml标识,表⽰该⽂件是xml格式的⽂件。例如<?xml version="1.0" encoding="UTF-8"?>。
3.定义属性时有两种⽅式:单⾏定义和多⾏定义。例如:
<!-- 单⾏定义的⽅式 -->
<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分钟的空闲时间才被杀掉。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论