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

2.1总体设计

为了使读者能更深刻地理解Tomcat的相关组件概念,我们将采用一种启发式的讲解方式来介 绍Tomcat的总体设计。从如何设计一个应用服务器开始,逐步完善,直至最终推导岀Tomcat的整体架构。

2.1.1 Server

从最基本的功能来讲,我们可以将服务器描述为这样一个应用:

它接收其他计算机(客户端)发来的请求数据并进行解析,完成相关业务处理,然 后把处理结果作为响应返回给请求计算机(客户端)。

通常情况下,我们通过使用Socket监听服务器指定端口来实现该功能。按照该描述,一个最 简单的服务器设计如图2-1所示。

我们通过start。方法启动服务器,打开Socket链接,监听服务器端口,并负责在接收到客户 端请求时进行处理并返回响应。同时提供一个stop ()方法来停止服务器并释放网络资源。

如果我们设计的不是一款服务器,仅仅是作为嵌入在应用系统中的一个远程请求处理方案, 且我们的应用系统访问量很低,那么这也许是个可行方案。

但是,我们设计的是应用服务器。

2.1.2 Connector 和 Container

很快我们就会发现,将请求监听与请求处理放到一起扩展性很差,比如当我们想适配多种网 络协议,但是请求处理却相同的时候。要知道自从Tomcat诞生起,它就始终支持与Apache集成, 无论是通过AJP协议还是通过HTTP协议。当Web应用通过Tomcat独立部署时,我们选择使用HTTP 协议为客户端提供服务;当通过Apache进行集群部署时,我们使用AJP协议与Wed服务器(Apache ) 进行链接。应用服务器(Tomcat)在两种部署架构下切换时,应确保Web应用不需做任何变更。

那么我们如何通过面向对象的方式来解决这个问题?自然的想法就是将网络协议与请求处 理从概念上分离于是,我们做了如下改进(见图2-2)。

一个Server可以包含多个Connector和Container。其中Connector负责开启Socke併监听客户端 请求、返回响应数据;Container负责具体的请求处理。Connector和Container分别拥有自己的start。 和stop()方法来加载和释放自己维护的资源。

但是,这个设计有个明显的缺陷。既然Server可以包含多个Connector和Container,那么如何 知晓来自某个Connector的请求由哪个Container处理呢?当然,我们可以维护一个复杂的映射规则 来解决这个问题,但是这并不是必需的,后续章节你会发现Container的设计已经足够灵活,并不 需要一个Connect。儲接到多个Container。更合理的方式如图2-3所示。
一个Server包含多个Service (它们互相独立,只是共享一个JVM以及系统类库),一个Service 负责维护多个Connector和一个Container,这样来自Connector的请求只能由它所属Service维护的 Container 处理。

在Tomcat中,Container是一个更加通用的概念。为了与Tomcat中的组件命名一致,我们将 Container?新命名为Engine,用以表示整个Servlet引擎。修改后的设计如图2-4所示。

注意 需要注意此处的描述,Engine表示整个Servlet引擎,而非Servlet容器。表示整个Servlet容器的是Server。引擎只负责请求的处理,并不需要考虑请求链接、协议等的处理。
2.1.3?Container 设计

上一节的设计已经解决了网络协议和容器的解耦,但是应用服务器是用来部署并运行Web 应用的,是一个运行环境,而不是一个独立的业务处理系统。因此,我们需要在Engine容器中 支持管理Web应用,当接收到Connector的处理请求时,Engine容器能够找到一个合适的Web应用 来处理。

那么在图2-4的设计方案的基础上,一种比较朴素的实现方案如图2-5所示。我们使用Context来表示一个Web应用,并且一个Engine可以包含多个Context。

注意:Context也拥有start()和stop。方法,用以在启动时加载资源以及在停止时释放资源。采 用这种方式设计,我们将加载和卸载资源的过程分解到每个组件当中,使组件充分解耦, 提高服务器的可扩展性和可维护性。在后续讲解过程中,新增组件多数也会有相同方法, 我们不再赘述。

这是不是个合理的方案呢?

设想我们有一台主机,它承担了多个域名的服务,如news.mycompany.com和article. mycompany.com均由该主机处理,我们应如何实现呢?当然,我们可以在该主机上运行多个服务 器实例,但是如果我们希望运行一个服务器实例呢?因为,作为应用服务器,我们应提供尽量灵 活的部署方式。

既然我们要提供多个域名的服务,那么就可以将每个域名视为一个虚拟的主机,在每个虚拟 主机下包含多个Web应用。因为对于客户端用户来说,他们并不了解服务端使用几台主机来为他们提供服务,只知道每个域名提供了哪些服务,因此,应用服务器将每个域名抽象为一个虚拟主 机从概念上是合理的。根据这个想法修改后的设计如图2-6所示
我们用Host表小虚拟主机的概念,—Host可以包含多[‘Context。

注意: 在Tomcat的设计中,Engine既可以包含Host,又可以包含Context,这是由具体的Engine 实现确定的,而且Tomcat采用一种通用的概念解决此问题,我们在后续部分会详细讲解。 Tomcat提供的默认实现StandardEngine只能包含Host。

如果阅读Servlet规范,我们就会知道,在一个Web应用中,可包含多个Servlet实例以处理来 自不同链接的请求。因此,我们还需要一个组件概念来表示Servlet定义。在Tomcat中,Servlet定 义被称为Wrapper,基于此修改后的设计如图2-7所示。
截至目前,我们多次提到“容器”这个概念。尽管在具体的小节中,容器的含义并不相同, 有时候指Engine,有时候指Context,但是它却代表了一类组件,这类组件的作用就是处理接收自 客户端的请求并且返回响应数据。尽管具体操作可能会委派到子组件完成,但是从行为定义上, 它们是一致的。基于这个概念,我们再次修正了我们的设计,如图2-8所示。

我们使用Container来表示容器,Container可以添加并维护子容器,因此Engine、Host、Context, Wrapper均继承自Container。我们将它们之间的组合关系改为虚线,以表示它们之间是弱依赖的 关系,即它们之间的关系是通过Container的父子容器的概念体现的。不过Service持有的是Engine 接口(8.5.6版本之前为Container接口,更加通用)。

注意: 既然Tomcat的Container可以表示不同的概念级别:Servlet引擎、虚拟主机、Web应用和 Servlet,那么我们就可以将不同级别的容器作为处理客户端请求的组件,这具体由我们 提供的服务器的复杂度决定。假使我们以嵌入式的方式启动Tomcat,且运行极其简单的 请求处理,不必支持多Web应用的场景,那么我们完全可以只在Service中维护一个简化 版的Engine ( 8.5.6之前甚至可以直接由Service维护一个Context)o当然,Tomcat的默认实 现采用了图2-8这种最灵活的方式,只是,我们要了解Tomcat的模型设计理论上的可伸缩 性,这也是一个中间件产品架构设计所需要重点关注的。此外,Tomcat的Container还有一个很重要的功能,就是后台处理。在很多情况下,我们的 Container需要执行一些异步处理,而且是定期执行,如每隔30秒执行一次,Tomcat对于Web应用 文件变更的扫描就是通过该机制实现的。Tomcat针对后台处理,在Container上定义了 backgroundprocess()方法,并且其基础抽象类(ContainerBase )确保在启动组件的同时,异步 启动后台处理。因此,在绝大多数情况下,各个容器组件仅需要实现Container的backgroundprocess。 方法即可,不必考虑创建异步线程。

2.1.4 Lifecycle

在进一步深入细化应用服务器设计之前,我们希望从抽象和复用层面再审视一下当前的设计 成果,使概念更加清晰,提供通用性定义用于应用服务器的统一管理。

我们很容易发现,所有组件均存在启动、停止等生命周期方法,拥有生命周期管理的特性。 因此,我们可以基于生命周期管理进行一次接口抽象,如图2-9所示。

我们针对所有拥有生命周期管理特性的组件抽象了一个Lifecycle通用接口,该接口定义了生 命周期管理的核心方法。

□ Init():初始化组件。

□?start():启动组件。

□?stop():停止组件。

□?destroy():销毁组件。

同时,该接口支持组件状态以及状态之间的转换,支持添加事件监听器(LifecycleListener) 用于监听组件的状态变化。如此,我们可以采用一致的机制来初始化、启动、停止以及销毁各个 组件。如Tomcat核心组件的默认实现均继承自LifecycleMBeanBase抽象类,该类不但负责组件各个 状态的转换和事件处理,还将组件自身注册为MBean,以便通过Tomcat的管理工具进行动态维护。

Tomcat中Lifecycle接口状态图如图2-10所示。

首先,每个生命周期方法可能对应数个状态的转换,以start()为例,即分为启动前、启动 中、已启动,这3个状态之间自动转换(所有标识为auto的转换路径都是在生命周期方法中自动 转换的,不再需要额外的方法调用)。
其次,并不是每个状态都会触发生命周期事件,也不是所有生命周期事件均存在对应状态。 状态与应用生命周期事件的对应如表2-1所示。
从表2-1中我们可以详细地看到每个生命周期方法影响的组件状态以及每个状态触发的事 件。此外,我们还注意到,Tomcat默认提供了3个与状态无关的事件类型,其中PERIODIC_EVENT 主要用于Container的后台定时处理,每次调用后触发该事件。CONFIGURE_START_EVENT和 CONFIGURE_STOP_EVENT的使用在后续章节中将会讲到。

PS:学习是循序渐进的,被气馁,相信自己,你可以的!!
get更多学习资料:https://shimo.im/docs/TC9Jq63Tp6HvTXdg

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

时间: 2024-11-08 20:09:15

Tomcat总体架构:Server+Container 设计+Lifecycle等的相关文章

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

2.1.5?Pipeline 和 Valve 从架构设计的角度来考虑,至此的应用服务器设计主要完成了我们对核心概念的分解,确保 了整体架构的可伸缩性和可扩展性,除此之外,我们还要考虑如何提高每个组件的灵活性,使其同样易于扩展. 在增强组件的灵活性和可扩展性方面,职责链模式是一种比较好的选择.Tomcat即采用该模 式来实现客户端请求的处理--请求处理也是职责链模式典型的应用场景之一.换句话说,在 Tomcat中每个Container组件通过执行一个职责链来完成具体的请求处理. Tomcat定义了

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 系统架构与设计模式,第 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.主要