Tomcat的整体架构和请求处理流程-《Tomcat内核设计剖析》读书笔记

前言

本文主要内容如下:
在这里插入图片描述
在这里插入图片描述

从整体预览Tomcat

如果将Tomcat内核高度抽象,则它可以看成由连接器(Connector)组件和容器(Container)组件组成,其中Connector组件负责在服务器端处理客户端连接,包括接收客户端连接、接收客户端的消息报文以及消息报文的解析等工作,而Container组件则负责对客户端的请求进行逻辑处理,并把结果返回给客户端。

Container组件包括4个级别的容器:Engine组件、Host组件、Context组件和Wrapper组件。
>> [插图]

从Tomcat服务器配置文件server.xml的内容格式看,它所描述的Tomcat也符合上述的层级结构,以下便是server.xml简洁的配置节点,所以从server.xml文件也能看出Tomcat的大体结构。

<? xml version='1.0' encoding='utf-8'? >
 <Server>
            	<Listener/>
                 <GlobalNamingResources>
                 <Resource/>
                 </GlobalNamingResources> 
                 <Service>
                         <Executor/>
                         <Connector/>
                         <Engine>
                                <Cluster/>
                                <Realm/> 
                                <Host>
                                     <Context/>
                                </Host>
                         </Engine>
                 </Service>
 </Server>

Server组件

Server是最顶级的组件,它代表Tomcat的运行实例,在一个JVM中只会包含一个Server。在Server的整个生命周期中,不同阶段会有不同的事情要完成。为了方便扩展,它引入了监听器方式,所以它也包含了Listener组件。另外,为了方便在Tomcat中集成JNDI,引入了GlobalNamingResources组件。同时,还包含了Service核心组件。

Service组件

Service是服务的抽象,它代表请求从接收到处理的所有组件的集合。如图所示,在设计上Server组件可以包含多个Service组件,每个Service组件都包含了若干用于接收客户端消息的Connector组件和处理请求的Engine组件。
在这里插入图片描述
其中,不同的Connector组件使用不同的通信协议,如HTTP协议和AJP协议。若干Connector组件和一个客户端请求处理组件Engine组成的集合即为Service。此外,Service组件还包含了若干Executor组件,每个Executor都是一个线程池,它可以为Service内所有组件提供线程池执行任务。

Connector组件

Connector主要的职责就是接收客户端连接并接收消息报文,消息报文经由它解析后送往容器中处理。如图所示,因为存在不同的通信协议,例如HTTP协议、AJP协议等,所以我们需要不同的Connector组件,每种协议对应一个Connector组件。
在这里插入图片描述
Connector组件的内部实现也会根据网络I/O的不同方式而不同分为阻塞I/O和非阻塞I/O。下面以HTTP协议为例,看看阻塞I/O和非阻塞I/O的Connector内部实现模块有什么不同。

在阻塞I/O方式下,Connector的结构如图所示。
在这里插入图片描述

  • Http11Protocol组件,是HTTP协议1.1版本的抽象,它包含接收客户端连接、接收客户端消息报文、报文解析处理、对客户端响应等整个过程。它主要包含JIoEndpoint组件和Http11Processor组件。启动时,JIoEndpoint组件内部的Acceptor组件将启动某个端口的监听,一个请求到来后将被扔进线程池Executor,线程池进行任务处理,处理过程中将通过Http11Processor组件对HTTP协议解析并传递到Engine容器继续处理。
  • Mapper组件,客户端请求的路由导航组件,通过它能对一个完整的请求地址进行路由,通俗地说,就是它能通过请求地址找到对应的Servlet。
  • CoyoteAdaptor组件,一个将Connector和Container适配起来的适配器。

如图所示,在非阻塞I/O方式下,Connector的结构类似阻塞模式,Http11Protocol组件改成Http11NioProtocol组件,JIoEndpoint组件改成NioEndpoint, Http11Processor组件改成Http11NioProcessor组件,这些类似的组件的功能也都类似。唯独多了一个Poller组件,它的职责是在非阻塞I/O方式下轮询多个客户端连接,不断检测、处理各种事件,例如不断检测各个连接是否有可读,对于可读的客户端连接则尝试进行读取并解析消息报文。
在这里插入图片描述

Engine组件

Tomcat内部有4个级别的容器,分别是Engine、Host、Context和Wrapper。Engine代表全局Servlet引擎,每个Service组件只能包含一个Engine容器组件,但Engine组件可以包含若干Host容器组件。
除了Host之外,它还包含如下组件。

  • Listener组件:可以在Tomcat生命周期中完成某些Engine容器相关工作的监听器。
  • AccessLog组件:客户端的访问日志,所有客户端访问都会被记录。
  • Cluster组件:它提供集群功能,可以将Engine容器需要共享的数据同步到集群中的其他Tomcat实例上。
  • Pipeline组件:Engine容器对请求进行处理的管道。
  • Realm组件:提供了Engine容器级别的用户-密码-权限的数据对象,配合资源认证模块使用。

Host组件

Tomcat中Host组件代表虚拟主机,这些虚拟主机可以存放若干Web应用的抽象(Context容器)。

Context组件

Context组件是Web应用的抽象,我们开发的Web应用部署到Tomcat后运行时就会转化成Context对象。它包含了各种静态资源、若干Servlet(Wrapper容器)以及各种其他动态资源。

Wrapper组件

Wrapper容器是Tomcat中4个级别的容器中最小的,与之相对应的是Servlet,一个Wrapper对应一个Servlet。它包含如下组件。

  • Servlet组件:Servlet即Web应用开发常用的Servlet,我们会在Servlet中编写好请求的逻辑处理。
  • ServletPool组件:Servlet对象池,当Web应用的Servlet实现了SingleThreadModel接口时则会在Wrapper中产生一个Servlet对象池。线程执行时,需先从对象池中获取到一个Servlet对象,ServletPool组件能保证Servlet对象的线程安全。
  • Pipeline组件:Wrapper容器对请求进行处理的管道。

Tomcat的请求流转过程

在这里插入图片描述
这里假定Tomcat作为专门处理HTTP的Web服务器,而且使用阻塞I/O方式接受客户端的连接。下面介绍请求流转的具体过程。
① 当Tomcat 启动后,Connector组件的接收器(Acceptor)将会监听是否有客户端套接字连接并接收Socket。
② 一旦监听到客户端连接,则将连接交由线程池Executor处理,开始执行请求响应任务。
③ Http11Processor组件负责从客户端连接中读取消息报文,然后开始解析HTTP的请求行、请求头部、请求体。将解析后的报文封装成Request 对象,方便后面处理时通过Request对象获取HTTP协议的相关值。
④ Mapper组件根据HTTP协议请求行的URL属性值和请求头部的Host属性值匹配由哪个Host容器、哪个Context容器、哪个Wrapper容器处理请求,这个过程其实就是根据请求从Tomcat中找到对应的Servlet。然后将路由的结果封装到Request对象中,方便后面处理时通过Request对象选择容器。
⑤ CoyoteAdaptor组件负责将Connector组件和Engine容器连接起来,把前面处理过程中生成的请求对象Request和响应对象Response传递到Engine容器,调用它的管道。
⑥ Engine容器的管道开始处理请求,管道里包含若干阀门(Valve),每个阀门负责某些处理逻辑。这里用xxxValve代表某阀门,我们可以根据自己的需要往这个管道中添加多个阀门,首先执行这个xxxValve,然后才执行基础阀门EngineValve,它会负责调用Host容器的管道。
⑦ Host容器的管道开始处理请求,它同样也包含若干阀门,首先执行这些阀门,然后执行基础阀门HostValve,它继续往下调用Context容器的管道。
⑧ Context容器的管道开始处理请求,首先执行若干阀门,然后执行基础阀门ContextValve,它负责调用Wrapper容器的管道。
⑨ Wrapper容器的管道开始处理请求,首先执行若干阀门,然后执行基础阀门WrapperValve,它会执行该Wrapper容器对应的Servlet对象的处理方法,对请求进行逻辑处理,并将结果输出到客户端。以上便是一个客户端请求到达Tomcat后处理的整体流程。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值