一. Tomcat 体系架构

Posted 岁月玲珑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一. Tomcat 体系架构相关的知识,希望对你有一定的参考价值。

一. Tomcat 体系架构

1. 什么是 Web 服务器?

其实并没有标准定义。一般认为,Web 服务器一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以向浏览器等 Web 客户端提供文 档,也可以放置网站文件,让全世界浏览;可以放置数据文件,让全世界下载什么是 Tomcat

2. 什么是 Tomcat

Tomcat 是一款开源轻量级 Web 应用服务器,是一款优秀的 Servlet 容器实现。

Servlet(Server Applet)是 Java Servlet 的简称,称为小服务程序或服务连接器,用 Java 编写的服务器端程序,具有独立于平台和协议的特性,主要 功能在于交互式地浏览和生成数据,生成动态 Web 内容。

Servlet 严格来讲是指 Java 语言实现的一个接口,一般情况下我们说的 Servlet 是指任何实现了这个 Servlet 接口的类。

实例化并调用 init()方法初始化该 Servlet,一般 Servlet 只初始化一次(只有一个对象)

service()(根据请求方法不同调用 doGet() 或者 doPost(),此外还有 doHead()、doPut()、doTrace()、doDelete()、doOptions()、destroy())。

当 Server 不再需要 Servlet 时(一般当 Server 关闭时),Server 调用 Servlet 的 destroy() 方法。

1. 典型的 Servlet 的处理流程

  1. 第一个到达服务器的 HTTP 请求被委派到 Servlet 容器。

  2. Servlet 容器在调用 service() 方法之前加载 Servlet。

  3. 然后 Servlet 容器处理由多个线程产生的多个请求,每个线程执行一个单一的 Servlet 实例的 service() 方法

3. Tomcat 版本介绍

**Servlet2.X:**项目目录结构必须要有 WEB-INF,web.xml 等文件夹和文件,在 web.xml 中配置 servlet,filter,listener,以 web.xml 为 java web 项目的统一 入口

servlet 3.x项目中可以不需要 WEB-INF,web.xml 等文件夹和文件,在没有 web.xml 文件的情况下,通过注解实现 servlet,filter, listener 的声 明,当使用注解时,容器自动进行扫描。

同时 Tomcat8.5 进行了大量的代码重构,对比与 7.0 的版本,也符合 Tomcat 未来的代码架构体系。但是 Tomcat 的核心和主体架构还是一直保持不变。

1. 8.5 版本特点

支持 Servlet3.1

默认采用 NIO,移除 BIO

支持 NIO2(AIO)

支持 HTTP/2 协议

默认采用异步日志处理

太老的版本比如 6.0 的版本 Servlet 不支持 3 所以会导致部署 SpringBoot 等项目有问题,同时这个版本是在 9.0 出现以后发布的一个中间版本,主体架构延续 8.0,同时又实现了部分 9.0 的新特性。

4. Tomcat 启动

下载地址

https://tomcat.apache.org/download-80.cg

1. 一般启动

startup.bat/sh

# 或者
catalina.bat start

2. IDE 中启动

3. 嵌入式启动

SpringBoot 中一个 main 方法嵌入式启动 Tomcat

@SpringBootApplication
public class Main 
    public static void main(String[] args) 
        SpringApplication.run(Main.class, args);
    

4. Debug 启动

在项目发布后,我们有时候需要对基于生产环境部署的应用进行调试,以解决在开发环境无法重现的 BUG。这时我们就需要用到应用服务器的远程 调试功能,这个主要是基于 JDK 提供的 JPDA(Java Platform Debugger Architecture,Java 平台调试体系结构)。不过一般情况下用不到。

使用 IDEA 远程部署 tomcat 和调试

  1. 在 catalina.sh 文件中加入以下的配置
CATALINA_OPTS="-Dcom.sun.management.jmxremote 
-Dcom.sun.management.jmxremote.port=1099 
-Dcom.sun.management.jmxremote.ssl=false 
-Dcom.sun.management.jmxremote.authenticate=false 
-Djava.rmi.server.hostname=192.168.1.134
-agentlib:jdwp=transport=dt_socket,address=15833,suspend=n,server=y"export CATALINA_OPTS

以上端口可以随意改动,但是必要的是后续的设置必须保持一致,并且务必保证端口没有被占用,这些设置的端口在防火墙中是开放 状态;

其中 1099 的是 tomcat 远程部署连接端口;

15833 是远程调试的端口;

192.168.19.200 是远程的服务器的 Ip

  1. 在 Linux 上启动 tomcat,使用命令启动

    ./bin/catalina.sh run &
    
  2. 使用ide的远程连接

5. Tomcat 项目部署及目录结构

1. 项目部署

a. 隐式部署

直接丢文件夹、war、jar 到 webapps 目录,tomcat 会根据文件夹名称自动生成虚拟路径,简单,但是需要重启 Tomcat 服务器,包括要修改端口和访问路径的也需要重启。

如果部署页面没有权限怎么办

更具提示添加用户角色即可

tomcat-users.xml

<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<role rolename="manager-status"/>
<role rolename="manager-jmx"/>

<user username="admin" password="admin" roles="manager-gui,admin-gui,manager-status"/>

重启生效

b. 显式部署

添加 context 元素

server.xml 中的 Host 加入一个 Context(指定路径和文件地址),例如:

<Host name="localhost"> 
<Context path="/cat" docBase="D:\\tomcat\\cat.war" />

即/comet 这个虚拟路径映射到了 D:\\work_tomcat\\ref-comet 目录下(war 会解压成文件),修改完 servler.xml 需要重启 tomcat 服务器。

创建 xml 文件

在 conf/Catalina/localhost 中创建 xml 文件,访问路径为文件名,例如:

在 localhost 目录下新建 demo.xml,内容为:

<Context path="/cat" docBase="D:\\tomcat\\cat.war" />

不需要写 path,虚拟目录就是文件名 demo,path 默认为/demo,添加 demo.xml 不需要重启 tomcat 服务器。

对比: 三种方式比较

**隐式部署:**可以很快部署,需要人手动移动 Web 应用到 webapps 下,在实际操作中不是很人性化,不需要重启

server.xml中添加 context 元素 : 配置速度快,需要配置两个路径,如果 path 为空字符串,则为缺省配置,每次修改 server.xml 文件后都要重新启动 Tomcat 服务器,重新部署.

conf/Catalina/localhost下创建 xml 文件:服务器后台会自动部署,修改一次后台部署一次,不用重复启动 Tomcat 服务器,该方式显得更为智能化。

2. bin 执行脚本目录

startup 文件,主要是检查 catalina.bat/sh 执行所需环境,并调用 catalina.bat 批处理文件。启动 tomcat。

catalina 文件,真正启动 Tomcat 文件,可以在里面设置 jvm 参数。后面性能调优会重点讲

shutdown 文件,关闭 Tomcat

脚本 version.sh、startup.sh、shutdown.sh、configtest.sh 都是对 catalina.sh 的包装,内容大同小异,差异在于功能介绍和调用 catalina.sh 时的参数不同。

Version:查看当前 tomcat 的版本号,

Configtest:校验 tomcat 配置文件 server.xml 的格式、内容等是否合法、正确。

Service:安装 tomcat 服务,可用 net start tomcat 启动

3. conf 配置目录

0. web.xml

Tomcat 中所有应用默认的部署描述文件,主要定义了基础的 Servlet 和 MIME 映射(mime-mapping 文件类型,其实就是 Tomcat 处理的文件类型),如果 部署的应用中不包含 Web.xml,那么 Tomcat 将使用此文件初始化部署描述,反之,Tomcat 会在启动时将默认描述与定义描述配置进行合并。

加载一些 tomcat 内置的 servlet

DefaultServlet 默认的,加载静态文件 html,js,jpg 等静态文件。 (tomcat不合适处理静态文件,需要使用nginx,f5做静态分离)

JspServlet 专门处理 jsp。

1. server.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- Server 代表一个 Tomcat 实例。可以包含一个或多个 Services,其中每个 Service 都有自己的 Engine 和 Connectors。 port="8005"指定一个端口,这个端口负责监听关闭 tomcat 的请求 -->
<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"/>
	<!-- 全局命名资源,定义了 UserDatabase 的一个 JNDI(java 命名和目录接口),通过 pathname 的文件得到一个用户授权的内存数据库 -->
	<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 它包含一个<Engine>元素,以及一个或多个<Connector>,这些 Connector 元素共享用同一个 Engine 元素 -->
	<Service name="Catalina">
		<!-- 每个 Service 可以有一个或多个连接器<Connector>元素, 第一个 Connector 元素定义了一个 HTTP Connector,它通过 8080 端口接收 HTTP 请求;第二个 Connector 元素定 义了一个 JD Connector,它通过 8009 端口接收由其它服务器转发过来的请求. -->
		<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>
		<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>
		<!-- 每个 Service 只能有一个<Engine>元素 -->
		<Engine name="Catalina" defaultHost="localhost">
			<Realm className="org.apache.catalina.realm.LockOutRealm">
				<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
			</Realm>
			<!-- 默认 host 配置,有几个域名就配置几个 Host,但是这种只能是同一个端口号 -->
			<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
				<!-- Tomcat 的访问日志,默认可以关闭掉它,它会在 logs 文件里生成 localhost_access_log 的访问日志 -->
				<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t " %r" %s %b"/>
			</Host>
			<Host name="www.hzg.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
				<Context path="" docBase="/myweb1"/>
				<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="hzg_access_log" suffix=".txt" pattern="%h %l %u %t " %r" %s %b"/>
			</Host>
		</Engine>
	</Service>
</Server>

Server是一个tomcat实例, 可以有多个Listener和多个Service,

一个Service有一个Engine和多个Connector

一个Engine可以有多个Host

一个Host可以有多个Context

Valve可以出现在各个组件里面

server.xml 中日志的 patter 解释

有效的日志格式模式可以参见下面内容,如下字符串,其对应的信息由指定的响应内容取代:

%a - 远程 IP 地址

%A - 本地 IP 地址

%b - 发送的字节数,不包括 HTTP 头,或“ - ”如果没有发送字节

%B - 发送的字节数,不包括 HTTP 头

%h - 远程主机名

%H - 请求协议

%l (小写的 L)- 远程逻辑从 identd 的用户名(总是返回’ - ')

%m - 请求方法

%p - 本地端口

%q - 查询字符串(在前面加上一个“?”如果它存在,否则是一个空字符串

%r - 第一行的要求

%s - 响应的 HTTP 状态代码

%S - 用户会话 ID

%t - 日期和时间,在通用日志格式

%u - 远程用户身份验证

%U - 请求的 URL 路径

%v - 本地服务器名

%D - 处理请求的时间(以毫秒为单位)

%T - 处理请求的时间(以秒为单位)

%I (大写的 i) - 当前请求的线程名称

2. context.xml

用于自定义所有 Web 应用均需要加载的 Context 配置,如果 Web 应用指定了自己的 context.xml,那么该文件的配置将被覆盖。

context.xml 与 server.xml 中配置 context 的区别

server.xml 是不可动态重加载的资源(Engine,Connector,Host启动时候就确定了),服务器一旦启动了以后,要修改这个文件,就得重启服务器才能重新加载。而 context.xml 文件(上下文可以切换)则不然,tomcat服务器会定时去扫描这个文件。一旦发现文件被修改(时间戳改变了),就会自动重新加载这个文件,而不需要重启服务器。

3. catalina.policy

权限相关 Permission ,Tomcat 是跑在 jvm 上的,所以有些默认的权限

4. tomcat-users.xml

配置 Tomcat 的 server 的 manager 信息

<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
<role rolename="manager-gui"/>
<role rolename="admin-gui"/>
<role rolename="manager-status"/>
<role rolename="manager-jmx"/>

<user username="admin" password="admin" roles="manager-gui,admin-gui,manager-status"/>
</tomcat-users>

5. logging.properties

设置 tomcat 日志

控制输出不输出内容到文件,不能阻止生成文件,阻止声文件可用注释掉

4. webapps 目录

存放 web 项目的目录,其中每个文件夹都是一个项目;如果这个目录下已经存在了目录,那么都是 tomcat 自带的。项目。其中 ROOT 是一个特殊的 项目,在地址栏中没有给出项目目录时,对应的就是 ROOT 项目。http://localhost:8080/examples,进入示例项目。其中 examples 就是项目名,即文件夹 的名字。

5. lib 目录

Tomcat 的类库,里面是一大堆 jar 文件。如果需要添加 Tomcat 依赖的 jar 文件,可以把它放到这个目录中,当然也可以把应用依赖的 jar 文件放到这 个目录中,这个目录中的 jar 所有项目都可以共享之,但这样你的应用放到其他 Tomcat 下时就不能再共享这个目录下的 Jar 包了,所以建议只把 Tomcat 需要的 Jar 包放到这个目录下;

6. work 目录

运行时生成的文件,最终运行的文件都在这里。通过 webapps 中的项目生成的!可以把这个目录下的内容删除,再次运行时会生再次生成 work 目录。 当客户端用户访问一个 JSP 文件时,Tomcat 会通过 JSP 生成 Java 文件,然后再编译 Java 文件生成 class 文件,生成的 java 和 class 文件都会存放到这个目 录下。

7. temp 目录

存放 Tomcat 的临时文件,这个目录下的东西可以在停止 Tomcat 后删除!

8. logs 目录

这个目录中都是日志文件,记录了 Tomcat 启动和关闭的信息,如果启动 Tomcat 时有错误,那么异常也会记录在日志文件中

localhost-xxx.log Web 应用的内部程序日志,建议保留

catalina-xxx.log

控制台日志host-manager.xxx.log

Tomcat 管理页面中的 host-manager 的操作日志,建议关闭

localhost_access_log_xxx.log 用户请求 Tomcat 的访问日志(这个文件在 conf/server.xml 里配置),建议关闭

conf 配置文件目录

6. Tomcat 组件及架构

Engine,Host,Context,Wrapper都被称为容器的组件

1. Server

Server 是最顶级的组件,它代表 Tomcat 的运行实例,它掌管着整个 Tomcat 的生死大权;

  1. 提供了监听器机制,用于在 Tomcat 整个生命周期中对不同时间进行处理

  2. 提供 Tomcat 容器全局的命名资源实现,JNDI

  3. 监听某个端口以接受 SHUTDOWN 命令,用于关闭 Tomcat

主要是监听功能

2. Service

一个概念,一个 Service 维护多个 Connector 和一个 Container

3. Connector 组件

链接器监听转换 Socket 请求,将请求交给 Container 处理,支持不同协议以及不同的 I/O 方式

就是我们socket编程中对应的socket.accept()方法对应的功能

4. Container

抽象出来的概念, 表示能够执行客户端请求并返回响应的一类对象,其中有不同级别的容器:Engine、Host、Context、Wrapper

5. Engine

整个 Servlet 引擎,最高级的容器对象, 一个Service只能有一个Engine

6. Host

表示 Servlet 引擎中的虚拟机,主要与域名有关,一个服务器有多个域名是可以使用多个 Host

7. Context

用于表示 ServletContext,一个 ServletContext 表示一个独立的 Web 应用, 主要和域名下的上下文路径关联, 所以一个域名可以有多个上下文路径

8. Wrapper

用于表示 Web 应用中定义的 Servlet

9. Executor

Tomcat 组件间可以共享的线程池

2. Tomcat 的核心组件

解耦:网络协议与容器的解耦。(容器只需和连接器打交道, 不用管使用的具体的通信协议, 连接器都会统一封装

即,我们熟知的Request 和Response对象)

Connector 链接器封装了底层的网络请求(Socket 请求及相应处理),提供了统一的接口,使 Container 容器与具体的请求协议以及 I/O 方式解耦。

Connector 将 Socket 输入转换成 Request 对象,交给 Container 容器进行处理,处理请求后,Container 通过 Connector 提供的 Response 对象将结果写入输出流。

因为无论是 Request 对象还是 Response 对象都没有实现 Servlet 规范对应的接口(这样多是不是为了让Connector和Serlvet解耦),Container 会将它们进一步分装成 ServletRequest 和 ServletResponse.

所以Connector和Servlet解耦, Container和Servlet耦合, 所以叫做Servlet容器, 而Connector不是

1. Tomcat 的链接器

<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/>

AJP 主要是用于 Web 服务器与 Tomcat 服务器集成,AJP 采用二进制传输可读性文本,使用保持持久性的 TCP 链接,使得 AJP 占用更少的带宽,并且链接开销要小得多,但是由于 AJP 采用持久化链接,因此有效的连接数较 HTTP 要更多

HTTP2.0 目前市场不成熟。

对于 I/0 选择,要根据业务场景来定,一般高并发场景下,APR 和 NIO2 的性能要优于 NIO 和 BIO,(linux 操作系统支持的 NIO2 由于是一个假的,并没有真正实现 AIO(NIO2就是指的AIO),所以一般 linux 上推荐使用 NIO,如果是 APR 的话,需要安装 APR 库,而 Windows 上默认安装了),所以在 8.5 的版本中默认是 NIO。

tomcat架构分析(概览)

出处:http://gearever.iteye.com 

Tomcat是目前应用比较多的servlet容器。关于tomcat本身的特点及介绍,网上已经有很多描述了,这里不再赘述。Tomcat除了能够支撑通常的web app外,其本身高度模块化的架构体系,也能带来最大限度的可扩展性。目前tomcat版本已经衍生到tomcat7,但是主流的版本还是tomcat6。此系列架构体系介绍还是以tomcat6为蓝本。 
Tomcat是有一系列逻辑模块组织而成,这些模块主要包括: 

  • 核心架构模块,例如Server,Service,engine,host和context及wrapper等
  • 网络接口模块connector
  • log模块
  • session管理模块
  • jasper模块
  • naming模块
  • JMX模块
  • 权限控制模块
  • ……


这些模块会在相关的文档里逐一描述,本篇文档以介绍核心架构模块为主。 

核心架构模块说明 
核心架构模块之间是层层包含关系。例如可以说Service是Server的子组件,Server是Service的父组件。在server.xml已经非常清晰的定义了这些组件之间的关系及配置。 
需要强调的是Service中配置了实际工作的Engine,同时配置了用来处理时间业务的线程组Executor(如果没有配置则用系统默认的WorkThread模式的线程组),以及处理网络socket的相关组件connector。详细情况如图所示。 
技术分享图片 
图中,1:n代表一对多的关系;1:1代表一对一的关系。 

StandEngine, StandHost, StandContext及StandWrapper是容器,他们之间有互相的包含关系。例如,StandEngine是StandHost的父容器,StandHost是StandEngine的子容器。在StandService内还包含一个Executor及Connector。 
1) Executor是线程池,它的具体实现是java的concurrent包实现的executor,这个不是必须的,如果没有配置,则使用自写的worker thread线程池 
2) Connector是网络socket相关接口模块,它包含两个对象,ProtocolHandler及Adapter 

  • ProtocolHandler是接收socket请求,并将其解析成HTTP请求对象,可以配置成nio模式或者传统io模式
  • Adapter是处理HTTP请求对象,它就是从StandEngine的valve一直调用到StandWrapper的valve


分层建模 
对于上述的各个逻辑模块,理解起来可能比较抽象。其实一个服务器无非是接受HTTP request,然后处理请求,产生HTTP response通过原有连接返回给客户端(浏览器)。那为什么会整出这么多的模块进行处理,这些模块是不是有些多余。 
其实这些模块各司其职,我们从底层wrapper开始讲解,一直上溯到顶层的server。这样易于理解。通过这些描述,会发现这正是tomcat架构的高度模块化的体现。这些细分的模块,使得tomcat非常健壮,通过一些配置和模块定制化,可以很大限度的扩展tomcat。 
首先,我们以一个典型的页面访问为例,假设访问的URL是 

引用
http://www.mydomain.com/app/index.html


详细情况如图所示。 
技术分享图片 

  • Wrapper封装了具体的访问资源,例如 index.html
  • Context 封装了各个wrapper资源的集合,例如 app
  • Host 封装了各个context资源的集合,例如 www.mydomain.com


按照领域模型,这个典型的URL访问,可以解析出三层领域对象,他们之间互有隶属关系。这是最基本的建模。从上面的分析可以看出,从wrapper到host是层层递进,层层组合。那么host 资源的集合是什么呢,就是上面所说的engine。 如果说以上的三个容器可以看成是物理模型的封装,那么engine可以看成是一种逻辑的封装。 

好了,有了这一整套engine的支持,我们已经可以完成从engine到host到context再到某个特定wrapper的定位,然后进行业务逻辑的处理了(关于怎么处理业务逻辑,会在之后的blog中讲述)。就好比,一个酒店已经完成了各个客房等硬件设施的建设与装修,接下来就是前台接待工作了。 

先说线程池,这是典型的线程池的应用。首先从线程池中取出一个可用线程(如果有的话),来处理请求,这个组件就是connector。它就像酒店的前台服务员登记客人信息办理入住一样,主要完成了HTTP消息的解析,根据tomcat内部的mapping规则,完成从engine到host到context再到某个特定wrapper的定位,进行业务处理,然后将返回结果返回。之后,此次处理结束,线程重新回到线程池中,为下一次请求提供服务。 

如果线程池中没有空闲线程可用,则请求被阻塞,一直等待有空闲线程进行处理,直至阻塞超时。线程池的实现有executor及worker thread两种。缺省的是worker thread 模式。 

至此,可以说一个酒店有了前台接待,有了房间等硬件设施,就可以开始正式运营了。那么把engine,处理线程池,connector封装在一起,形成了一个完整独立的处理单元,这就是service,就好比某个独立的酒店。 

通常,我们经常看见某某集团旗下酒店。也就是说,每个品牌有多个酒店同时运营。就好比tomcat中有多个service在独自运行。那么这多个service的集合就是server,就好比是酒店所属的集团。 

作用域 
那为什么要按层次分别封装一个对象呢?这主要是为了方便统一管理。类似命名空间的概念,在不同层次的配置,其作用域不一样。以tomcat自带的打印request与response消息的RequestDumperValve为例。这个valve的类路径是: 

引用
org.apache.catalina.valves.RequestDumperValve

 

valve机制是tomcat非常重要的处理逻辑的机制,会在相关文档里专门描述。 如果这个valve配置在server.xml的节点下,则其只打印出访问这个app(my)的request与response消息。 

Xml代码
<Host name="localhost" appBase="webapps"  
          unpackWARs="true" autoDeploy="true"  
          xmlValidation="false" xmlNamespaceAware="false">  
             <Context path="/my" docBase=" /usr/local/tomcat/backup/my" >  
                   <Valve className="org.apache.catalina.valves.RequestDumperValve"/>  
             </Context>  
             <Context path="/my2" docBase=" /usr/local/tomcat/backup/my" >  
             </Context>  
  </Host>

 

如果这个valve配置在server.xml的节点下,则其可以打印出访问这个host下两个app的request与response消息。 

Xml代码
<Host name="localhost" appBase="webapps"  
                unpackWARs="true" autoDeploy="true"  
                xmlValidation="false" xmlNamespaceAware="false">  
                    <Valve className="org.apache.catalina.valves.RequestDumperValve"/>  
                    <Context path="/my" docBase=" /usr/local/tomcat/backup/my" >  
                    </Context>  
                    <Context path="/my2" docBase=" /usr/local/tomcat/backup/my" >   
                    </Context>  
  </Host>

 

在这里贴一个缺省的server.xml的配置,通过这些配置可以加深对tomcat核心架构分层模块的理解,关于tomcat的配置,在相关的文档里另行说明。为了篇幅,我把里面的注释给删了。 

Xml代码
<Server port="8005" shutdown="SHUTDOWN">  
         <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />  
         <Listener className="org.apache.catalina.core.JasperListener" />   
         <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />  
         <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />  
         <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">  
               <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"   
                     maxThreads="150" minSpareThreads="4"/>  
               <Connector port="80" protocol="HTTP/1.1"   
                     connectionTimeout="20000"   
                     redirectPort="7443" />  
               <Connector port="7009" protocol="AJP/1.3" redirectPort="7443" />  
               <Engine name="Catalina" defaultHost="localhost">  
                    <Realm className="org.apache.catalina.realm.UserDatabaseRealm"  
                           resourceName="UserDatabase"/>  
                    <Host name="localhost" appBase="webapps"  
                           unpackWARs="true" autoDeploy="true"  
                           xmlValidation="false" xmlNamespaceAware="false">  
                           <Context path="/my" docBase="/usr/local/tomcat/backup/my" >  
                           </Context>   
                    </Host>   
                </Engine>  
            </Service>  
  </Server>

 

至此,头脑中应该有tomcat整体架构的概念。有时间在写些其他模块的东西。



































以上是关于一. Tomcat 体系架构的主要内容,如果未能解决你的问题,请参考以下文章

tomcat架构分析(概览)

tomcat架构分析-索引

Tomcat卷一 ----架构和初始化源码分析

(转)关于Tomcat的点点滴滴(体系架构处理http请求的过程安装和配置目录结构设置压缩和对中文文件名的支持以及Catalina这个名字的由来……等)

聊聊Tomcat的架构设计

TodoTomcat与Jetty的比较 以及Tomcat架构的学习