Tomcat——Tomcat系统架构与原理分析

一、简介

Tomcat服务器是一个免费的开放源码的Web应用服务器,目前是应用比较广泛的。

从Tomcat的7.0版本开始支持Servlet3.0规范规范,可以支持我们开发过程中不再配置web.xml。

浏览器访问服务器的流程

浏览器访问服务器使用的是http协议,http是应用层协议,用于定义数据通信的格式,具体的数据传输使用的是TCP/IP协议。

  • 1、用户向浏览器发起http请求。
  • 2、浏览器接收到用户请求,向服务器发起TCP连接请求。
  • 3、服务器接收到浏览器请求,并建立TCP连接。
  • 4、浏览器生成HTTP数据包,向服务器发送数据包。
  • 5、服务器收到浏览器发送过来的数据包必能解析,执行请求对应的具体逻辑,将返回数据组装成http格式包并返回。
  • 6、浏览器接收到服务器返回的http的数据包,解析http数据包,通过浏览器将相应静态资源呈现给用户。
  • 1、用户通过浏览器进行了一个操作,比如输入网址并回车,或者是点击链接,接着浏览 器获取了这个事件。
  • 2、浏览器向服务端发出TCP连接请求。
  • 3、服务程序接受浏览器的连接请求,并经过TCP三次握手建立连接。
  • 4、浏览器将请求数据打包成一个HTTP协议格式的数据包。
  • 5、浏览器将该数据包推入网络,数据包经过网络传输,最终达到端服务程序。
  • 6、服务端程序拿到这个数据包后,同样以HTTP协议格式解包,获取到客户端的意图。
  • 7、得知客户端意图后进行处理,比如提供静态文件或者调用服务端程序获得动态结果。
  • 8、服务器将响应结果(可能是HTML或者图片等)按照HTTP协议格式打包。
  • 9、服务器将响应数据包推入网络,数据包经过网络传输最终达到到浏览器。
  • 10、浏览器拿到数据包后,以HTTP协议的格式解包,然后解析数据,假设这里的数据是 HTML。
  • 11、浏览器将HTML文件展示在页面上。

那我们想要探究的Tomcat作为一个HTTP服务器,主要是接受连接、解析请求数据、处理请求和发送响应这几个步骤。

Http服务器请求处理

浏览器发给服务端的是一个HTTP格式的请求,HTTP服务器收到这个请求后,需要调用服务端程序来处理,所谓的服务端程序就是写的Java类,一般来说不同的请求需要由不同 的Java类来处理。

HTTP服务器不直接调用业务类,而是把请求交给容器来处理,容器通过Servlet接口调用业务类。因此Servlet接口和Servlet容器的出现,达到了HTTP服务器与 业务类解耦的目的。而Servlet接口和Servlet容器这一整套规范叫作Servlet规范。 Tomcat按照Servlet规范的要求实现了Servlet容器,同时它们也具有HTTP服务器的功能。作为Java程序员,如果我们要实现新的业务功能,只需要实现一个Servlet,并把它注册到Tomcat(Servlet容器)中,剩下的事情就由Tomcat帮我们处理了。

Servlet容器工作流程

为了解耦,HTTP服务器不直接调用Servlet,而是把请求交给Servlet容器来处理。当客户请求某个资源时,HTTP服务器会用一个ServletRequest对象把客户的请求信息封 装起来,然后调用Servlet容器的service方法,Servlet容器拿到请求后,根据请求的URL 和Servlet的映射关系,找到相应的Servlet,如果Servlet还没有被加载,就用反射机制创 建这个Servlet,并调用Servlet的init方法来完成初始化,接着调用Servlet的service方法 来处理请求,把ServletResponse对象返回给HTTP服务器,HTTP服务器会把响应发送给 客户端。

二、Tomcat整体架构

我们知道如果要设计一个系统,首先是要了解需求,我们已经了解了Tomcat要实现两个核心功能:

  • 1、处理Socket连接,负责网络字节流与Request和Response对象的转化。
  • 2、加载和管理Servlet,以及具体处理Request请求。

因此Tomcat设计了两个核心组件连接器(Connector)和容器(Container)来分别做这两件事情。连接器负责对外交流,容器负责内部处理。

2.1、Tomcat连接器组件Coyote

2.1.1、连接器 - Coyote

Coyote 是Tomcat的连接器框架的名称 , 是Tomcat服务器提供的供客户端访问的外部接口。客户端通过Coyote与服务器建立连接、发送请求并接受响应 。

  • 1、Coyote 封装了底层的网络通信(Socket 请求及响应处理),为Catalina 容器提供了统一 的接口,使Catalina 容器与具体的请求协议及IO操作方式完全解耦。
  • 2、Coyote 将Socket 输 入转换封装为 Request 对象,交由Catalina 容器进行处理,处理请求完成后,Catalina 通 过Coyote 提供的Response 对象将结果写入输出流 。
  • 3、Coyote 作为独立的模块,只负责具体协议和IO的相关操作,与Servlet 规范实现没有直接关系,因此即便是Request 和 Response 对象也并未实现Servlet规范对应的接口,而是在Catalina中将他们进一步封装为ServletRequest和ServletResponse 。

2.1.2、IO模型与协议

在Coyote中,Tomcat支持的多种I/O模型和应用层协议,具体包含哪些IO模型和应用层协议,请看下表:
Tomcat 支持的IO模型(自8.5/9.0 版本起,Tomcat 移除了 对 BIO 的支持):

IO模型 描述
NIO 非阻塞I/O,采用Java NIO类库实现。
NIO2 异步I/O,采用JDK 7最新的NIO2类库实现。
APR 采用Apache可移植运行库实现,是C/C++编写的本地库。如果选择该方 案,需要单独安装APR库。

Tomcat 支持的应用层协议 :

应用层协议 描述
HTTP/1.1 这是大部分Web应用采用的访问协议。
AJP 用于和Web服务器集成(如Apache),以实现对静态资源的优化以及 集群部署,当前支持AJP/1.3。
HTTP/2 HTTP 2.0大幅度的提升了Web性能。下一代HTTP协议 , 自8.5以及9.0 版本之后支持。

协议分层 :


在 8.0 之前 , Tomcat 默认采用的I/O方式为 BIO , 之后改为 NIO。 无论 NIO、NIO2 还是 APR, 在性能方面均优于以往的BIO。 如果采用APR, 甚至可以达到 Apache HTTP Server 的影响性能。

Tomcat为了实现支持多种I/O模型和应用层协议,一个容器可能对接多个连接器,就好比一个房间有多个门。但是单独的连接器或者容器都不能对外提供服务,需要把它们组装起来才能工作,组装后这个整体叫作Service组件。这里请你注意,Service本身没有做什么重要的事情,只是在连接器和容器外面多包了一层,把它们组装在一起。Tomcat内可能有多个Service,这样的设计也是出于灵活性的考虑。通过在Tomcat中配置多个Service,可以实现通过不同的端口号来访问同一台机器上部署的不同应用。

2.1.3、 连接器组件

连接器中的各个组件的作用如下:

EndPoint
  • 1、EndPoint : Coyote 通信端点,即通信监听的接口,是具体Socket接收和发送处理 器,是对传输层的抽象,因此EndPoint用来实现TCP/IP协议的。
  • 2、Tomcat 并没有EndPoint 接口,而是提供了一个抽象类AbstractEndpoint , 里面定 义了两个内部类:Acceptor和SocketProcessor。Acceptor用于监听Socket连接请求。 SocketProcessor用于处理接收到的Socket请求,它实现Runnable接口,在Run方法里 调用协议处理组件Processor进行处理。为了提高处理能力,SocketProcessor被提交到 线程池来执行。而这个线程池叫作执行器(Executor),我在后面的专栏会详细介绍 Tomcat如何扩展原生的Java线程池。
Processor

Processor:Coyote 协议处理接口 ,如果说EndPoint是用来实现TCP/IP协议的,那么 Processor用来实现HTTP协议,Processor接收来自EndPoint的Socket,读取字节流解 析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理, Processor是对应用层协议的抽象。

ProtocolHandler

ProtocolHandler: Coyote 协议接口, 通过Endpoint 和 Processor , 实现针对具体协 议的处理能力。Tomcat 按照协议和I/O 提供了6个实现类 : AjpNioProtocol , AjpAprProtocol, AjpNio2Protocol , Http11NioProtocol ,Http11Nio2Protocol , Http11AprProtocol。我们在配置tomcat/conf/server.xml 时 , 至少要指定具体的 ProtocolHandler , 当然也可以指定协议名称 , 如 : HTTP/1.1 ,如果安装了APR,那么 将使用Http11AprProtocol , 否则使用 Http11NioProtocol 。

Adapter

由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类 来“存放”这些请求信息。ProtocolHandler接口负责解析请求并生成Tomcat Request类。 但是这个Request对象不是标准的ServletRequest,也就意味着,不能用Tomcat Request作为参数来调用容器。Tomcat设计者的解决方案是引入CoyoteAdapter,这是 适配器模式的经典运用,连接器调用CoyoteAdapter的Sevice方法,传入的是Tomcat Request对象,CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调用容 器的Service方法。

2.3、容器 - Catalina

Tomcat是一个由一系列可配置的组件构成的Web容器,而Catalina是Tomcat的servlet容器。Catalina是Servlet容器实现,包含了之前讲到的所有的容器组件,以及后续涉及到 的安全、会话、集群、管理等Servlet 容器架构的各个方面。它通过松耦合的方式集成 Coyote,以完成按照请求协议进行数据读写。同时,它还包括我们的启动入口、Shell程 序等。

2.3.1、Catalina依赖关系

从另一个角度来说,Tomcat本质上就是一款Servlet容器,因为Catalina才是Tomcat的核心,其他模块都是为Catalina提供支撑的。比如:通过Coyote模块提供连接通信,Jasper模块提供JSP引擎,Naming提供JNDI服务,Juli提供日志服务。

2.3.2、Catalina 结构

Catalina 的主要组件结构如下:


如上图所示,Catalina负责管理Server,而Server表示着整个服务器。Server下面有多个 服务Service,每个服务都包含着多个连接器组件Connector(Coyote 实现)和一个容器 组件Container。在Tomcat 启动的时候, 会初始化一个Catalina的实例。

Catalina 各个组件的职责:

组件 职责
Catalina 负责解析Tomcat的配置文件 , 以此来创建服务器Server组件,并根据 命令来对其进行管理
Server 服务器表示整个Catalina Servlet容器以及其它组件,负责组装并启动 Servlet引擎,Tomcat连接器。Server通过实现Lifecycle接口,提供了 一种优雅的启动和关闭整个系统的方式
Service 服务是Server内部的组件,一个Server包含多个Service。它将若干个 Connector组件绑定到一个Container(Engine)上
Connector 连接器,处理与客户端的通信,它负责接收客户请求,然后转给相关 的容器处理,最后向客户返回响应结果
Container 容器,负责处理用户的servlet请求,并返回对象给web用户的模块

2.3.3、 Container结构

Tomcat设计了4种容器,分别是Engine、Host、Context和Wrapper。这4种容器不是平行关系,而是父子关系。, Tomcat通过一种分层的架构,使得Servlet容器具有很好的灵 活性。


各个组件的含义 :

容器 描述
Engine 表示整个Catalina的Servlet引擎,用来管理多个虚拟站点,一个Service 最多只能有一个Engine,但是一个引擎可包含多个Host
Host 代表一个虚拟主机,或者说一个站点,可以给Tomcat配置多个虚拟主 机地址,而一个虚拟主机下可包含多个Context
Context 表示一个Web应用程序, 一个Web应用可包含多个Wrapper
Wrapper 表示一个Servlet,Wrapper 作为容器中的最底层,不能包含子容器

我们也可以再通过Tomcat的server.xml配置文件来加深对Tomcat容器的理解。Tomcat 采用了组件化的设计,它的构成组件都是可配置的,其中最外层的是Server,其他组件按照一定的格式要求配置在这个顶层容器中。

<Server>
    <Service>
        <Connector>
        </Connector>
        <Engine>
            <Host>
                <Context></Context>
            </Host>
        </Engine>
    </Service>
</Server>

这些容器具有父子关系,形成一个树形结构,Tomcat通过组合模式来管理这些容器。
具体实现方法是,所有容器组件都实现了Container接口,因此组合模
式可以使得用户对单容器对象和组合容器对象的使用具有一致性。这里单容器对象指的
是最底层的Wrapper,组合容器对象指的是上面的Context、Host或者Engine。

Container 接口中提供了以下方法(截图中知识一部分方法) :


在上面的接口看到了getParent、SetParent、addChild和removeChild等方法。
Container接口扩展了LifeCycle接口,LifeCycle接口用来统一管理各组件的生命周期。

参考:
https://blog.csdn.net/qq_37551917/article/details/119681753

https://www.cnblogs.com/yifengGG/p/13124816.html

https://www.cnblogs.com/prliu/p/14298835.html

https://www.pianshen.com/article/75801608257/

https://www.cnblogs.com/sunlightlee/p/10994281.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352