Tomcat总体架构:Pipeline 和 Valve+Connector 设计+Executor等

2.1.5?Pipeline 和 Valve

从架构设计的角度来考虑,至此的应用服务器设计主要完成了我们对核心概念的分解,确保 了整体架构的可伸缩性和可扩展性,除此之外,我们还要考虑如何提高每个组件的灵活性,使其同样易于扩展。

在增强组件的灵活性和可扩展性方面,职责链模式是一种比较好的选择。Tomcat即采用该模 式来实现客户端请求的处理——请求处理也是职责链模式典型的应用场景之一。换句话说,在 Tomcat中每个Container组件通过执行一个职责链来完成具体的请求处理。

Tomcat定义了Pipeline (管道)和Valve (阀)两个接口。前者用于构造职责链,后者代表职 责链上的每个处理器。当然,我们还可以从字面意思来理解这两个接口所扮演的角色一来自客 户端的请求就像是流经管道的水一般,经过每个阀进行处理。其设计如图2-11所示。

Pipeline中维护了一个基础的Valve,它始终位于Pipeline的末端(即最后执行),封装了具体 的请求处理和输出响应的过程。然后,通过addValve()方法,我们可以为Pipeline添加其他的Valve 0 后添加的Valve位于基础Valve之前,并按照添加顺序执行。Pipeline通过获得首个Valve来启动整个链条的执行。

Tomcat容器组件的灵活之处在于,每个层级的容器(Engine, Host、Context, Wrapper )均有对应的基础Valve实现,同时维护了一个Pipeline实例。也就是说,我们可以在任何层级的容器 上针对请求处理进行扩展。

由于Tomcat每个层级的容器均通过Pipeline和Valve进行请求处理,那么,我们很容易将一些 通用的Valve实现根据需要添加到任何层级的容器上。

修改后的应用服务器设计如图2-12所示。

2.1.5?Connector 设计

前面我们重点讨论了容器组件的设计,集中于如何设计才能确保容器的灵活性和可扩展性, 并做到合理的解耦。接下来,我们再细化一下服务器设计中的另一个重要组件一onnector0

要想与Container配合实现一个完整的服务器功能,Connector至少要完成如下几项功能。

口监听服务器端口,读取来自客户端的请求。

□将请求数据按照指定协议进行解析。

□根据请求地址匹配正确的容器进行处理。

□将响应返回客户端。

只有这样才能保证将接收到的客户端请求交由与请求地址匹配的容器处理。我们知道,Tomcat支持多协议,默认支持HTTP和AJP。同时,Tomcat还支持多种I/O方式, 包括BIO ( 8.5版本之后移除)、NIO、APR。而且在Tomcat 8之后新增了对NIO2和HTTP/2协议的 支持。因此,对协议和I/O进行抽象和建模是需要重点关注的。

Tomcat的设计方案如图2-13所示。

在Tomcat中,ProtocolHandler表示一个协议处理器,针对不同协议和I/O方式,提供了不同的 实现,如Http 11 NioProtocol表示基于NIO的HTTP协议处理器。ProtocolHandler包含一个Endpoint 用于启动Socket监听,该接口按照I/O方式进行分类实现,如Nio2Endpoint表示非阻塞式Socket I/Oo 还包含一个Processor用于按照指定协议读取数据,并将请求交由容器处理,如HttpllNioProcessor 表示在NIO的方式下HTTP请求的处理类。

注意 :Tomcat并没有Endpoint接口,仅有AbstractEndpoint抽象类,此处仅作为概念讨论,故将其 视为 Endpoint 接口 。

在Connector启动时,Endpoint会启动线程来监听服务器端口,并在接收到请求后调用 Processor进行数据读取。具体过程见后续章节。

当Processor卖取客户端请求后,需要按照请求地址映射到具体的容器进行处理,这个过程即 为请求映射。由于Tomcat各个组件釆用通用的生命周期管理,而且可以通过管理工具进行状态变 更,因此请求映射除考虑映射规则的实现外,还要考虑容器组件的注册与销毁。

Tomcatil过Mapper和MapperListener两个类实现上述功能。前者用于维护容器映射信息,同 时按照映射规则(Servlet规范定义)查找容器。后者实现了ContainerListener和LifecycleListener, 用于在容器组件状态发生变更时,注册或者取消对应的容器映射信息。为了实现上述功能, MapperListener实现了Lifecycle接口,当其启动时(在Service启动时启动),会自动作为监听器注 册到各个容器组件上,同时将已创建的容器注册到Mapper。

注意 在Tomcat7及之前的版本中,Mapper由Connector维护,而在Tomcat8中,改由Service维护, 因为Service本来就是用于维护Connector和Container的组合,两者从概念上讲更密切一些。Tomcat通过适配器模式(Adapter )实现了Connector与Mapper、Container的解耦。Tomcat默 认的Connector实现(Coyote )对应的适配器为CoyoteAdapter。也就是说,如果你希望使用Tomcat 的链接器方案,但是又想脱离Servlet容器(虽然这种情况几乎不可能出现,但是从架构可扩展性 的角度来讲,还是值得讨论一下),此时只需要实现我们自己的Adapter即可。当然,我们还需要按照Container的定义开发我们自己的容器实现(不一定遵从Servlet规范)。

按照上述描述,Connector设计如图2-14所示。

2.1.5?Executor

完成了Connector的设计之后,我们再进一步审视一下当前的应用服务器方案,很明显,我们 忽略了一个问题——并发。这对应用服务器而言是尤其需要考虑的,我们不可能让所有来自客户 端的请求均以串行的方式执行。那么,我们应如何设计应用服务器的并发方案?

首先,回顾已经讲解的Tomcat设计方案,既然Tomcat提供了一致的可插拔的组件环境,那么 我们自然也希望线程池作为一个组件进行统一管理。因此,Tomcat提供了Executor接口来表示一 个可以在组件间共享的线程池(默认使用了JDK5提供的线程池技术),该接口同样继承自 Lifecycle,可按照通用的组件进行管理。

其次,线程池的共享范围如何确定?在Tomcat中Executor由Service维护,因此同一个Service 中的组件可以共享一个线程池。

当然,如果没有定义任何线程池,相关组件(如Endpoint)会自动创建线程池,此时,线程 池不再共享。

在Tomcat中,Endpoint会启动一组线程来监听Socket端口,当接收到客户端请求后,会创建 请求处理对象,并交由线程池处理,由此支持并发处理客户端请求。

这里我们仅从概念层面进行描述,Tomcat具体的线程池实现、使用方式、注意事项等会在后 续章节中详细描述。

添加Executor后,总体设计如图2-15所示。

2.1.5?Bootstrap 和 Catalina

我们在前面几个小节中讲解了 Tomcat总体架构中的主要核心组件,它们代表了应用服务器程 序本身,这就如楼房的主体。但是,除了主体建筑外,楼房还需要外墙等装饰,Tomcat也一样, 我们还需要提供一套配置环境来支持系统的可配置性,便于我们通过修改相关配置来优化应用服务器。

当然,我们没有涉及集群、安全等组件,尽管它们也非常重要,但是,我们还是希望更多 地关注于一些通用概念。虽然集群、安全等作为一个完备的应用服务器必不可少,但是它们的 缺失并不会影响我们去理解应用服务器的基本概念和设计方式。这些内容将会在后续章节中详细讲解。

在第1章中,我们列举了Tomcat的几个重要配置文件,其中最核心的文件为server.xml。通过 这个文件,我们可以修改Tomcat组件的配置参数甚至添加相关组件,这也是后续性能调优阶段重 点涉及的文件。

Tomcatil过类Catalina提供了一个Shell程序,用于解析server.xml创建各个组件,同时,负责 启动、停止应用服务器(只需要启动Tomcat顶层组件Server即可)。

Tomcat 使用Digester 解析 XML 文件,包括 server.xml 以及 web.xml 等,具体可参见 http://commons. apache.org/proper/commons-digester/,在讲解Tomcat酉己置时,我们也会再做进一步说明。

最后,Tomcat提供了Bootstrap作为应用服务器启动入口。Bootstrap负责创建Catalina实例,根 据执行参数调用Catalina相关方法完成针对应用服务器的操作(启动、停止)。

也许你会有疑问,为什么Tomcat不直接通过Catalina启动,而是又提供了Bootstrap呢?你可 以查看一下Tomcat的发布包目录,Bootstrap并不位于Tomcat的依赖库目录下($CATALINA_ HOME/lib ),而是直接在$CATALINA_HOME/bin目录下。Bootstrap与Tomcat应用服务器完全松耦 合(通过反射调用Catalina实例),它可以直接依赖JRE运行并为Tomcat应用服务器创建共享类加 载器,用于构造Catalina实例以及整个Tomcat服务器。

注意 Tomcat的启动方式可以作为非常好的示范来指导中间件产品设计。它实现了启动入口与 核心环境的解耦,这样不仅简化了启动(不必配置各种依赖库,因为只有独立的几个API), 而且便于我们更灵活地组织中间件产品的结构,尤其是类加载器的方案,否则,我们所 有的依赖库将统一放置到一个类加载器中,而无法做到灵活定制。

至此,我们应用服务器的完整设计如图2-16所示。

上述是Tomcat标准的启动方式。但是正如我们所说,既然Server及其子组件代表了应用服务 器本身,那么我们就可以不通过Bootstrap和Catalina来启动服务器。

Tomcat提供了一个同名类org.apache.catalina.startup.Tomcat,使用它我们可以将Tomcat 服务器嵌入到我们的应用系统中并进行启动。当然,你可以自己编写代码来启动Server,也可以 自定义其他配置方式启动,如YAML。这就是Tomcat灵活的架构设计带给我们的便利,也是我们 设计中间件产品的架构关注点之一。

最后,我们再整体回顾一下上述讲解涉及的Tomcat服务器中的概念,如表2-2所示。

至此,我们循序渐进地介绍了Tomcat总体架构的静态设计,接下来我们将从两个方面介绍 Tomcat的动态设计:应用服务器启动和客户端请求处理。这两个方面也是应用服务器基本的处理 过程。

提前get tomcat PDF文档:https://shimo.im/docs/TC9Jq63Tp6HvTXdg

原文地址:https://blog.51cto.com/14587687/2485602

时间: 2024-08-29 09:13:15

Tomcat总体架构:Pipeline 和 Valve+Connector 设计+Executor等的相关文章

tomcat总体架构

Tomcat 总体结构图 从上图中可以看出Tomcat的心脏是两个组件:Connector 和 Container,关于这两个组件将在后面详细介绍.Connector 组件是可以被替换,这样可以提供给服务器设计者更多的选择,因为这个组件是如此重要,不仅跟服务器的设计的本身,而且和不同的应用场景也十分相关,所以一个Container 可以选择对应多个Connector.多个Connector和一个Container 就形成了一个Service,Service 的概念大家都很熟悉了,有了Servic

Tomcat总体架构(Tomcat源码解析系列二)

Tomcat即是一个HTTP服务器,也是一个servlet容器,主要目的就是包装servlet,并对请求响应相应的servlet,纯servlet的web应用似乎很好理解Tomcat是如何装载servlet的,但,当使用一些MVC框架时,如spring MVC.strusts2,可能就找不出servlet在哪里?其实spring MVC框架就是一整个servlet,在web.xml中配置如下: <!-- Spring MVC servlet --> <servlet> <se

Tomcat总体架构:Server+Container 设计+Lifecycle等

2.1总体设计 为了使读者能更深刻地理解Tomcat的相关组件概念,我们将采用一种启发式的讲解方式来介 绍Tomcat的总体设计.从如何设计一个应用服务器开始,逐步完善,直至最终推导岀Tomcat的整体架构. 2.1.1 Server 从最基本的功能来讲,我们可以将服务器描述为这样一个应用: 它接收其他计算机(客户端)发来的请求数据并进行解析,完成相关业务处理,然 后把处理结果作为响应返回给请求计算机(客户端). 通常情况下,我们通过使用Socket监听服务器指定端口来实现该功能.按照该描述,一

Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析

Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析 这个分为两个部分的系列文章研究了 Apache Tomcat 服务器的系统架构以及其运用的很多经典设计模式.第 1 部分 分析了 Tomcat 的工作原理,第 2 部分将分析 Tomcat 中运用的许多经典设计模式,如模版模式.工厂模式和单例模式等.通过学习它们的实践运用能给我们以后的软件设计起到一定的借鉴作用. 门面设计模式 门面设计模式在 Tomcat 中有多处使用,在 Request 和 Response 对象封装中.Stan

Tomcat 系统架构与设计模式,第 1 部分: 工作原理

Tomcat 系统架构与设计模式,第 1 部分: 工作原理 这个分为两个部分的系列文章将研究 Apache Tomcat 的系统架构以及其运用的很多经典设计模式.本文是第 1 部分,将主要从 Tomcat 如何分发请求.如何处理多用户同时请求,还有它的多级容器是如何协调工作的角度来分析 Tomcat 的工作原理,这也是一个 Web 服务器首要解决的关键问题. 这个分为两个部分的系列文章将研究 Apache Tomcat 的系统架构以及其运用的很多经典设计模式.本文是第 1 部分,将主要从 Tom

【Tomcat】Tomcat 系统架构与设计模式,第 1 部分: 工作原理

这个分为两个部分的系列文章将研究 Apache Tomcat 的系统架构以及其运用的很多经典设计模式.本文是第 1 部分,将主要从 Tomcat 如何分发请求.如何处理多用户同时请求,还有它的多级容器是如何协调工作的角度来分析 Tomcat 的工作原理,这也是一个 Web 服务器首要解决的关键问题. 本文以 Tomcat 5 为基础,也兼顾最新的 Tomcat 6 和 Tomcat 4.Tomcat 的基本设计思路和架构是具有一定连续性的. Tomcat 总体结构 Tomcat 的结构很复杂,但

粗浅看 Tomcat系统架构分析

Tomcat的结构很复杂,但是Tomcat也非常的模块化,找到了Tomcat最核心的模块,就抓住了Tomcat的"七寸". 整体结构 Tomcat 总体结构图 从上图中可以看出Tomcat的心脏是两个组件:Connector 和 Container,关于这两个组件将在后面详细介绍.Connector 组件是可以被替换,这样可以提供给服务器设计者更多的选择,因为这个组件是如此重要,不仅跟服务器的设计的本身,而且和不同的应用场景也十分相关,所以一个Container 可以选择对应多个Con

Tomcat系统架构

Tomcat 系统架构与设计模式,第 1 部分 工作原理 系列内容: 此内容是该系列 2 部分中的第 1 部分: Tomcat 系统架构与设计模式 本文以 Tomcat 5 为基础,也兼顾最新的 Tomcat 6 和 Tomcat 4.Tomcat 的基本设计思路和架构是具有一定连续性的. Tomcat 总体结构 Tomcat 的结构很复杂,但是 Tomcat 也非常的模块化,找到了 Tomcat 最核心的模块,您就抓住了 Tomcat 的"七寸".下面是 Tomcat 的总体结构图:

服务器 : Apache Tomcat - 理解架构层次

文章概览 相信很多接触java的人都对Tom猫有着多少的熟悉,就个人而言,本来只知道Tom简单的操作与配置,就像裹上一层纱,迷迷糊糊的. Tomcat的书籍本来就不多,高分的还是很久之前的版本,直到最近看到下面这本书,解答了我的很多疑问,同时这篇文章将总结读书收获. 如果觉得文章写的内容是你感兴趣的或者我的猫使你感兴趣,建议你读读这本书. 该文会介绍Tom的架构,服务器如何从一层层抽象设计到完整的架构 Tomcat介绍 Tom是一款全世界著名的轻量级应用服务器,基于java,服务于java.主要