详述tomcat中的l配置⽂件⽰例
正⽂
1 前⾔
Tomcat ⾪属于 Apache 基⾦会,是开源的轻量级 Web 应⽤服务器,使⽤⾮常⼴泛。l是 Tomcat 中最重要的配置⽂件,l的每⼀个元素都对应了 Tomcat 中的⼀个组件;通过对XML ⽂件中元素的配置,可以实现对 Tomcat 中各个组件的控制。因此,学习l⽂件的配置,对于了解和使⽤ Tomcat ⾄关重要。
本⽂将通过实例,介绍l中各个组件的配置,并详细说明 Tomcat 各个核⼼组件的作⽤以及各个组件之间的相互关系。
说明:由于l⽂件中元素与 Tomcat 中组件的对应关系,后⽂中为了描述⽅便,“元素”和“组件”的使⽤不严格区分。
l配置实例
l位于$TOMCAT_HOME/conf⽬录下,下⾯是⼀个l实例。后⽂中将结合该实例讲解l中,各个元素的含义和作⽤;在阅读后续章节过程中,可以对照该 XML ⽂档进⾏理解。
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.JasperListener" />
<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" />
<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 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>
servlet和tomcat的关系</Engine>
</Service>
</Server>
l⽂档的整体结构和元素分类
3.1 整体结构
l的整体结构如下:
<Server>
<Service>
<Connector />
<Connector />
<Engine>
<Host>
<Context /><!-- 现在常常使⽤⾃动部署,不推荐配置Context元素,Context⼩节有详细说明 -->
</Host>
</Engine>
</Service>
</Server>
该结构中只给出了 Tomcat 的核⼼组件,除了核⼼组件外,Tomcat 还有⼀些其他组件,下⾯介绍⼀下组件的分类。
3.2 元素分类
l⽂件中的元素可以分为以下 4 类:
第 1 类:顶层元素,<Server>和<Service>
<Server>元素是整个配置⽂件的根元素,<Service>元素则代表⼀个Engine元素以及⼀组与之相连的Connector元素。
第 2 类:连接器,<Connector>
<Connector>代表了外部客户端发送请求到特定 Service 的接⼝;同时也是外部客户端从特定 Servic
e 接收响应的接⼝。
第 3 类:容器,<Engine>、<Host>和<Context>
容器的功能是处理 Connector 接收进来的请求,并产⽣相应的响应。Engine、Host 和 Context 都是容器,但它们不是平⾏的关系,⽽是⽗⼦关系:Engine 包含 Host,Host 包含 Context。⼀个Engine 组件可以处理 Service 中的所有请求,⼀个 Host 组件可以处理发向⼀个特定虚拟主机的所有请求,⼀个 Context 组件可以处理⼀个特定 Web 应⽤的所有请求。
第 4 类:内嵌组件,可以内嵌到容器中的组件
实际上,Server、Service、Connector、Engine、Host 和 Context 是最重要的最核⼼的 Tomcat 组件,其他组件都可以归为内嵌组件。下⾯将详细介绍 Tomcat 中各个核⼼组件的作⽤,以及相互之间的关系。
4 核⼼组件
本部分将分别介绍各个核⼼组件的作⽤、特点以及配置⽅式等。
4.1 Server
Server 元素在最顶层,代表整个 Tomcat 容器,因此它必须是l中唯⼀⼀个最外层的元素。⼀个 Server 元素中可以有⼀个或多个 Service 元素。
在第⼀部分的例⼦中,在最外层有⼀个<Server>元素,shutdown属性表⽰关闭 Server 的指令;port属性表⽰ Server 接收shutdown指令的端⼝号,设为-1可以禁掉该端⼝。
Server 的主要任务,就是提供⼀个接⼝让客户端能够访问到这个 Service 集合,同时维护它所包含的所有的 Service 的⽣命周期,包括如何初始化、如何结束服务、如何到客户端要访问的 Service 等。
4.2 Service
Service 的作⽤,是在 Connector 和 Engine 外⾯包了⼀层,把它们组装在⼀起,对外提供服务。⼀个 Service 可以包含多个 Connector,但是只能包含⼀个 Engine;其中 Connector 的作⽤是从客户端接收请求,Engine 的作⽤是处理接收进来的请求。
在第⼀部分的例⼦中,Server 中包含⼀个名称为Catalina的 Service。实际上,Tomcat 可以提供多个 Service,不同的 Service 监听不同的端⼝,后⽂会有介绍。
4.3 Connector
Connector 的主要功能,是接收连接请求,创建 Request 和 Response 对象⽤于和请求端交换数据;然后分配线程让 Engine 来处理这个请求,并把产⽣的 Request 和 Response 对象传给 Engine。 通过配置 Connector,可以控制请求 Service 的协议及端⼝号。在第⼀部分的例⼦中,Service 包含两个 Connector:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
通过配置第 1 个 Connector,客户端可以通过 8080 端⼝号使⽤http协议访问 Tomcat。其中,protocol属性规定了请求的协议,port规定了请求的端⼝号,redirectPort表⽰当强制要求https⽽请求是http时,重定向⾄端⼝号为 8443 的 Connector,connectionTimeout表⽰连接的超时时间。在这个例⼦中,Tomcat 监听 HTTP 请求,使⽤的是 8080 端⼝,⽽不是正式的 80 端⼝;实际上,在正式的⽣产环境中,Tomcat 也常常监听 8080 端⼝,⽽不是 80 端⼝。这是因为在⽣产环境中,很少将 Tomcat 直接对外开放接收请求,⽽是在 Tomcat 和客户端之间加⼀层代理服务器(如 nginx),⽤于请求的转发、负载均衡、处理静态⽂件等;通过代理服务器访问 Tomcat 时,是在局域⽹中,因此⼀般仍使⽤ 8080 端⼝。
通过配置第 2 个 Connector,客户端可以通过 8009 端⼝号使⽤AJP协议访问 Tomcat。AJP协议负责
和其他的 HTTP 服务器(如 Apache)建⽴连接;在把 Tomcat 与其他 HTTP 服务器集成时,就需要⽤到这个连接器。之所以使⽤ Tomcat 和其他服务器集成,是因为 Tomcat 可以⽤作 Servlet/JSP 容器,但是对静态资源的处理速度较慢,不如 Apache 和 IIS 等 HTTP 服务器;因此常常将 Tomcat 与 Apache 等集成,前者作 Servlet 容器,后者处理静态资源,⽽ AJP 协议便负责 Tomcat 和 Apache 的连接。Tomcat 与 Apache 等集成的原理如下图所⽰:
4.4 Engine
Engine 组件在 Service 组件中有且只有⼀个;Engine 是 Service 组件中的请求处理组件。Engine 组件从⼀个或多个 Connector 中接收请求并处理,并将完成的响应返回给 Connector,最终传递给客户端。
前⾯已经提到过,Engine、Host 和 Context 都是容器,但它们不是平⾏的关系,⽽是⽗⼦关系:Engine 包含 Host,Host 包含 Context。
在第⼀部分的例⼦中,Engine 的配置语句如下:
<Engine name="Catalina" defaultHost="localhost">
其中,name属性⽤于⽇志和错误信息,在整个 Server 中应该唯⼀。defaultHost属性指定了默认的 host 名称,当发往本机的请求指定的 host 名称不存在时,⼀律使⽤ defaultHost 指定的 host 进⾏处理;因此,defaultHost的值,必须与 Engine 中的⼀个 Host 组件的name属性值匹配。
4.5 Host
4.5.1 Engine 与 Host
Host 是 Engine 的⼦容器。Engine 组件中可以内嵌 1 个或多个 Host 组件,每个 Host 组件代表 Engi
ne 中的⼀个虚拟主机。Host 组件⾄少有⼀个,且其中⼀个的name必须与 Engine 组件的defaultHost属性相匹配。
4.5.2 Host 的作⽤
Host 虚拟主机的作⽤,是运⾏多个 Web 应⽤(⼀个 Context 代表⼀个 Web 应⽤),并负责安装、展开、启动和结束每个 Web 应⽤。
Host 组件代表的虚拟主机,对应了服务器中⼀个⽹络名实体(如st,或 IP 地址116.25.25.25),为了使⽤户可以通过⽹络名连接 Tomcat 服务器,这个名字应该在 DNS 服务器上注册。
客户端通常使⽤主机名来标识它们希望连接的服务器;该主机名也会包含在 HTTP 请求头中。Tomcat 从 HTTP 头中提取出主机名,寻名称匹配的主机。如果没有匹配,请求将发送⾄默认主机。因此默认主机不需要是在 DNS 服务器中注册的⽹络名,因为任何与所有 Host 名称不匹配的请求,都会路由⾄默认主机。
4.5.3 Host 的配置
在第⼀部分的例⼦中,Host 的配置如下:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
下⾯对其中配置的属性进⾏说明:
name属性指定虚拟主机的主机名,⼀个 Engine 中有且仅有⼀个 Host 组件的name属性与 Engine 组件的defaultHost属性相匹配;⼀般情况下,主机名需要是在 DNS 服务器中注册的⽹络名,但是Engine 指定的defaultHost不需要,原因在前⾯已经说明。
unpackWARs指定了是否将代表 Web 应⽤的 WAR ⽂件解压;如果为true,通过解压后的⽂件结构运⾏该 Web 应⽤,如果为false,直接使⽤ WAR ⽂件运⾏ Web 应⽤。
Host 的autoDeploy和appBase属性,与 Host 内 Web 应⽤的⾃动部署有关;此外,本例中没有出现的xmlBase和deployOnStartup属性,也与 Web 应⽤的⾃动部署有关;将在下⼀节(Context)中介绍。
4.6 Context
4.6.1 Context 的作⽤
Context 元素代表在特定虚拟主机上运⾏的⼀个 Web 应⽤。在后⽂中,提到 Context、应⽤或 Web
应⽤,它们指代的都是 Web 应⽤。每个 Web 应⽤基于 WAR ⽂件,或 WAR ⽂件解压后对应的⽬录(这⾥称为应⽤⽬录)。Context 是 Host 的⼦容器,每个 Host 中可以定义任意多的 Context 元素。
在第⼀部分的例⼦中,可以看到l配置⽂件中并没有出现 Context 元素的配置。这是因为,Tomcat 开启了⾃动部署,Web 应⽤没有在l中配置静态部署,⽽是由 Tomcat 通过特定的规则⾃动部署。下⾯介绍⼀下 Tomcat ⾃动部署 Web 应⽤的机制。
4.6.2 Web 应⽤⾃动部署
第 1 点:Host 的配置
要开启 Web 应⽤的⾃动部署,需要配置所在的虚拟主机;配置的⽅式就是前⾯提到的 Host 元素的deployOnStartup和autoDeploy属性。如果deployOnStartup和autoDeploy设置为true,则 tomcat 启动⾃动部署:当检测到新的 Web 应⽤或 Web 应⽤的更新时,会触发应⽤的部署(或重新部署)。⼆者的主要区别在于,deployOnStartup为true时,Tomcat 在启动时检查 Web 应⽤,且检测到的所有Web 应⽤视作新应⽤;autoDeploy为true时,Tomcat 在运⾏时定期检查新的 Web 应⽤或 Web 应⽤的更新。除此之外,⼆者的处理相似。
通过配置deployOnStartup和autoDeploy可以开启虚拟主机⾃动部署 Web 应⽤;实际上,⾃动部署
依赖于检查是否有新的或更改过的 Web 应⽤,⽽ Host 元素的appBase和xmlBase设置了检查 Web 应⽤更新的⽬录。
其中,appBase属性指定 Web 应⽤所在的⽬录,默认值是webapps,这是⼀个相对路径,代表 Tomcat 根⽬录下webapps⽂件夹。xmlBase属性指定 Web 应⽤的 XML 配置⽂件所在的⽬录,默认值为conf/<engine_name>/<host_name>,例如第⼀部分的例⼦中,主机localhost的xmlBase的默认值是$TOMCAT_HOME/conf/Catalina/localhost。
第 2 点:检查 Web 应⽤更新
⼀个 Web 应⽤可能包括以下⽂件:XML 配置⽂件,WAR 包,以及⼀个应⽤⽬录(该⽬录包含 Web 应⽤的⽂件结构);其中 XML 配置⽂件位于xmlBase指定的⽬录,WAR 包和应⽤⽬录位于
appBase指定的⽬录。Tomcat 按照如下的顺序进⾏扫描,来检查应⽤更新:
扫描虚拟主机指定的xmlBase下的 XML 配置⽂件;
扫描虚拟主机指定的appBase下的 WAR ⽂件;
扫描虚拟主机指定的appBase下的应⽤⽬录。
第 3 点:<Context>元素的配置
Context 元素最重要的属性是docBase和path,此外reloadable属性也⽐较常⽤。
docBase指定了该 Web 应⽤使⽤的 WAR 包路径,或应⽤⽬录。需要注意的是,在⾃动部署场景下(配置⽂件位于xmlBase中),docBase不在appBase⽬录中,才需要指定;如果docBase指定的WAR 包或应⽤⽬录就在docBase中,则不需要指定,因为 Tomcat 会⾃动扫描appBase中的 WAR 包和应⽤⽬录,指定了反⽽会造成问题。
path指定了访问该 Web 应⽤的上下⽂路径,当请求到来时,Tomcat 根据 Web 应⽤的path属性与 URI 的匹配程度来选择 Web 应⽤处理相应请求。例如,Web 应⽤app1的path属性是/app1,Web
应⽤app2的path属性是/app2,那么请求/app1/index.html会交由app1来处理;⽽请求/app2/index.html会交由app2来处理。如果⼀个 Context 元素的path属性为"",那么这个 Context 是虚拟主机的默认Web 应⽤;当请求的 URI 与所有的path都不匹配时,使⽤该默认Web应⽤来处理。
但是,需要注意的是,在⾃动部署场景下(配置⽂件位于xmlBase中),不能指定path属性,path属性由配置⽂件的⽂件名、WAR ⽂件的⽂件名或应⽤⽬录的名称⾃动推导出来。如扫描 Web 应⽤时,发现了xmlBase⽬录下的l,或appBase⽬录下的app1.WAR或app1应⽤⽬录,则该 Web 应⽤
的path属性是app1。如果名称不是app1⽽是ROOT,则该 Web 应⽤是虚拟主机默认的 Web 应⽤,此时path属性推导为""。
reloadable属性指⽰ Tomcat 是否在运⾏时监控在WEB-INF/classes和WEB-INF/lib⽬录下class⽂件的改动。如果值为true,那么当class⽂件改动时,会触发 Web 应⽤的重新加载。在开发环境
下,reloadable设置为true便于调试;但是在⽣产环境中设置为true会给服务器带来性能压⼒,因此reloadable参数的默认值为false。
下⾯来看⾃动部署时,xmlBase下的 XML 配置⽂件l的例⼦:
<Context docBase="D:\Program Files\app1.war" reloadable="true"/>
在该例⼦中,docBase位于 Host 的appBase⽬录之外;path属性没有指定,⽽是根据l⾃动推导为app1;由于是在开发环境下,因此reloadable设置为true,便于开发调试。
第 4 点:⾃动部署举例
最典型的⾃动部署,就是当我们安装完 Tomcat 后,$TOMCAT_HOME/webapps⽬录下有如下⽂件夹:
4.6.l中静态部署 Web 应⽤
除了⾃动部署,我们也可以在l中通过<context>元素静态部署 Web 应⽤。静态部署与⾃动部署是可以共存的。在实际应⽤中,并不推荐使⽤静态部署,因为l是不可动态重加载的资源,服务器⼀旦启动了以后,要修改这个⽂件,就得重启服务器才能重新加载。⽽⾃动部署可以在 Tomcat 运⾏时通过定期的扫描来实现,不需要重启服务器。l中使⽤ Context 元素配置 Web 应⽤,Context 元素应该位于 Host 元素中。举例如下:
<Context path="/" docBase="D:\Program Files \app1.war" reloadable="true"/>
docBase:静态部署时,docBase可以在appBase⽬录下,也可以不在;本例中,docBase不在appBase⽬录下;
path:静态部署时,可以显式指定path属性,但是仍然受到了严格的限制:只有当⾃动部署完全关闭(deployOnStartup和autoDeploy都为false)或docBase不在appBase中时,才可以设置path属性。在
本例中,docBase不在appBase中,因此path属性可以设置;
reloadable属性的⽤法与⾃动部署时相同。
5 核⼼组件的关联
5.1 整体关系
核⼼组件之间的整体关系,在上⼀部分有所介绍,这⾥总结⼀下:
Server 元素在最顶层,代表整个 Tomcat 容器;⼀个 Server 元素中可以有⼀个或多个 Service 元素。
Service 在 Connector 和 Engine 外⾯包了⼀层,把它们组装在⼀起,对外提供服务。⼀个 Service 可以包含多个 Connector,但是只能包含⼀个 Engine;Connector 接收请求,Engine 处理请求。
Engine、Host 和 Context 都是容器,且 Engine 包含 Host,Host 包含 Context。每个 Host 组件代表 Engine 中的⼀个虚拟主机;每个 Context 组件代表在特定 Host 上运⾏的⼀个 Web 应⽤。
5.2 如何确定请求由谁处理?
当请求被发送到 Tomcat 所在的主机时,如何确定最终哪个 Web 应⽤来处理该请求呢?
5.2.1 根据协议和端⼝号选定 Service 和 Engine
Service 中的 Connector 组件可以接收特定端⼝的请求,因此,当 Tomcat 启动时,Service 组件就会监听特定的端⼝。在第⼀部分的例⼦中,catalina这个 Service 监听了 8080 端⼝(基于 HTTP 协议)和 8009 端⼝(基于 AJP 协议)。当请求进来时,Tomcat 便可以根据协议和端⼝号选定处理请求的 Service;Service ⼀旦选定,Engine 也就确定。
通过在 Server 中配置多个 Service,可以实现通过不同的端⼝号来访问同⼀台机器上部署的不同应⽤。
5.2.2 根据域名或 IP 地址选定 Host
Service 确定后,Tomcat 在 Service 中寻名称与域名/IP 地址匹配的 Host 处理该请求。如果没有到,则使⽤ Engine 中指定的defaultHost来处理该请求。在第⼀部分的例⼦中,由于只有⼀个
Host(name属性为localhost),因此该 Service/Engine 的所有请求都交给该 Host 处理。
5.2.3 根据 URI 选定 Context/Web 应⽤
这⼀点在 Context ⼀节有详细的说明:Tomcat 根据应⽤的path属性与 URI 的匹配程度来选择 Web 应⽤处理相应请求,这⾥不再赘述。
5.2.4 举例
5.3 如何配置多个服务
通过在 Server 中配置多个 Service 服务,可以实现通过不同的端⼝号来访问同⼀台机器上部署的不同 Web 应⽤。在l中配置多服务的⽅法⾮常简单,分为以下⼏步:
复制<Service>元素,放在当前<Service>后⾯;
修改端⼝号:根据需要监听的端⼝号修改<Connector>元素的port属性;必须确保该端⼝没有被其他进程占⽤,否则 Tomcat 启动时会报错,⽽⽆法通过该端⼝访问 Web 应⽤。
以 Win7 为例,可以⽤如下⽅法出某个端⼝是否被其他进程占⽤:netstat -aon|findstr "8081"发现 8081 端⼝被 PID 为 2064 的进程占⽤,tasklist |findstr "2064"发现该进程为(这是 McAfee 杀毒软件的进程)。
修改 Service 和 Engine 的name属性;
修改 Host 的appBase属性(如webapps2)
Web 应⽤仍然使⽤⾃动部署;
将要部署的 Web 应⽤(WAR 包或应⽤⽬录)拷贝到新的appBase下。
以第⼀部分的l为例,多个 Service 的配置如下:
<?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.JasperListener" />
<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" />
<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 name="localhost" appBase="/opt/project/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>
<Service name="Catalina2">
<Connector port="8084" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
<Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina2" defaultHost="localhost">
<Realm className="org.alm.LockOutRealm">
<Realm className="org.alm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="/opt/project/webapps2" 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>
再将原webapps下的docs⽬录拷贝到webapps2中,则通过如下两个接⼝都可以访问docs应⽤:
6 其他组件
除核⼼组件外,l中还可以配置很多其他组件。下⾯只介绍第⼀部分例⼦中出现的组件,如果要了解更多内容,可以查看 Tomcat 官⽅⽂档。
6.1 Listener
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.JasperListener" />
<Listener className="org.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.ThreadLocalLeakPreventionListener" />
Listener(即)定义的组件,可以在特定事件发⽣时执⾏特定的操作;被监听的事件通常是 Tomcat 的启动和停⽌。可以在 Server、Engine、Host 或 Context 中,本例中的都是
在 Server 中。实际上,本例中定义的 6 个,都只能存在于 Server 组件中。不允许内嵌其他组件。
需要配置的最重要的属性是className,该属性规定了的具体实现类,该类必须实现了org.apache.catalina.LifecycleListener接⼝。下⾯依次介绍例⼦中配置的:VersionLoggerListener:当 Tomcat 启动时,该记录 Tomcat、Java 和操作系统的信息。该必须是配置的第⼀个。
AprLifecycleListener:Tomcat 启动时,检查 APR 库,如果存在则加载。APR,即 Apache Portable Runtime,是 Apache 可移植运⾏库,可以实现⾼可扩展性、⾼性能,以及与本地服务器技术更好的
集成。
JasperListener:在 Web 应⽤启动之前初始化 Jasper,Jasper 是 JSP 引擎,把 JVM 不认识的 JSP ⽂件解析成 Java ⽂件,然后编译成class⽂件供 JVM 使⽤。
JreMemoryLeakPreventionListener:与类加载器导致的内存泄露有关。
GlobalResourcesLifecycleListener:通过该,初始化<GlobalNamingResources>标签中定义的全局 JNDI 资源;如果没有该,任何全局资源都不能使⽤。<GlobalNamingResources>将在
后⽂介绍。
ThreadLocalLeakPreventionListener:当 Web 应⽤因thread-local导致的内存泄露⽽要停⽌时,该会触发线程池中线程的更新。当线程执⾏完任务被收回线程池时,活跃线程会⼀个⼀个的更新。
只有当 Web 应⽤(即 Context 元素)的renewThreadsWhenStoppingContext属性设置为true时,该才有效。
6.2 GlobalNamingResources 与 Realm
第⼀部分的例⼦中,Engine 组件下定义了 Realm 组件:
<Realm className="org.alm.LockOutRealm">
<Realm className="org.alm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
Realm,可以把它理解成“域”;Realm 提供了⼀种⽤户密码与 Web 应⽤的映射关系,从⽽达到⾓⾊安全管理的作⽤。在本例中,Realm 的配置使⽤name为 UserDatabase 的资源实现。⽽该资源在
Server 元素中使⽤ GlobalNamingResources 配置:
<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>
GlobalNamingResources 元素定义了全局资源,通过配置可以看出,该配置是通过读取$TOMCAT_HOME/l实现的。
6.3 Valve
在第⼀部分的例⼦中,Host 元素内定义了 Valve 组件:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
单词 Valve 的意思是“阀门”,在 Tomcat 中代表了请求处理流⽔线上的⼀个组件;Valve 可以与 Tomcat 的容器(Engine、Host 或 Context)关联。不同的 Valve 有不同的特性,下⾯介绍⼀下本例中出现
的 AccessLogValve。
AccessLogValve 的作⽤是通过⽇志记录其所在的容器中处理的所有请求,在本例中,Valve 放在 Host 下,便可以记录该 Host 处理的所有请求。AccessLogValve 记录的⽇志就是访问⽇志,每天的
请求会写到⼀个⽇志⽂件⾥。AccessLogValve 可以与 Engine、Host 或 Context 关联;在本例中,只有⼀个 Engine,Engine 下只有⼀个 Host,Host 下只有⼀个 Context,因此 AccessLogValve 放在三
个容器下的作⽤其实是类似的。本例的 AccessLogValve 属性的配置,使⽤的是默认的配置;下⾯介绍 AccessLogValve 中各个属性的作⽤:
className:规定了 Valve 的类型,是最重要的属性;本例中,通过该属性规定了这是⼀个 AccessLogValve。
directory:指定⽇志存储的位置,本例中,⽇志存储在$TOMCAT_HOME/logs⽬录下。
prefix:指定了⽇志⽂件的前缀。
suffix:指定了⽇志⽂件的后缀。通过directory、prefix和suffix的配置,在$TOMCAT_HOME/logs⽬录下,可以看到如下所⽰的⽇志⽂件。
pattern:指定记录⽇志的格式,本例中各项的含义如下:
%h:远程主机名或 IP 地址;如果有 Nginx 等反向代理服务器进⾏请求分发,该主机名/IP 地址代表的是 Nginx,否则代表的是客户端。后⾯远程的含义与之类似,不再解释。
%l:远程逻辑⽤户名,⼀律是-,可以忽略。
%u:授权的远程⽤户名,如果没有,则是-。
%t:访问的时间。
%r:请求的第⼀⾏,即请求⽅法(Get/Post 等)、URI 及协议。
%s:响应状态,200、404等等。
%b:响应的数据量,不包括请求头,如果为0,则是-。
例如,下⾯是访问⽇志中的⼀条记录
pattern的配置中,除了上述各项,还有⼀个⾮常常⽤的选项是%D,含义是请求处理的时间(单位是毫秒),对于统计分析请求的处理速度帮助很⼤。
开发⼈员可以充分利⽤访问⽇志,来分析问题、优化应⽤。例如,分析访问⽇志中各个接⼝被访问的⽐例,不仅可以为需求和运营⼈员提供数据⽀持,还可以使⾃⼰的优化有的放⽮;分析访问⽇志中各个请求的响应状态码,可以知道服务器请求的成功率,并出有问题的请求;分析访问⽇志中各个请求的响应时间,可以出慢请求,并根据需要进⾏响应时间的优化。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论