Tomcat之请求处理响应过程

经过上篇Tomcat架构简述,我们了解到Tomcat的结构和模块化,模块之间的关系。因此,到这里,就像我们已经盖好一座大楼,并将其装饰成了酒店。分配了前台(Connector),其他工作服务人员(Container),已经对每层(Host),每个房间(Context)和房间布局装饰成不同的格局(Wrapper)。
那么,该如何开业,进行接收旅客,给他们分配房间,并提供完美的服务后退回房间,这样一个闭环的流程呢?

疑问

所以可以将上边的问题拆分成对于Tomcat的四个疑问:
1)Connector如何接受请求的?
2)如何将请求封装成Request和Response的?
3)如何把Request和Response交给Container进行处理的?
4)Container处理完之后如何交给Connector并返回给客户端的?
首先看一下Connector的结构图(图B),如下所示:

分析

Connector中具体用ProtocolHandler来处理请求的,不同的ProtocolHandler代表不同的连接类型(如Http11Protocol使用普通的Socket来连接,Http11NioProtocol使用NioSocket连接)如下图
在这里插入图片描述
ProtocolHandler的三个重要组件:

  • Endpoint(用于处理底层Socket的网络连接,用来实现TCP/IP协议)
  • Processor(用于将Endpoint接收到的Socket封装成Request,用来实现HTTP协议)
  • Adapter(用于将Request交给Container进行具体处理,即将请求适配到Servlet容器)

Endpoint的抽象实现AbstractEndpoint。并且AbstractEndpoint中定义了一个内部类和一个接口

  • Acceptor(监听请求)
  • Handler(处理接收到的Socket在内部调用Processor进行处理)
    在这里插入图片描述
    ProtocolHandler的抽象实现AbstractProtocol中定义了一个内部类AsyncTimeout(检查异步request的超时)
    在这里插入图片描述

现在,我们上边的疑问中,1)、2)、3)都得到了一个简单的答案。
那么第 4)个呢,下面我们就来具体看看Container是如何进行处理请求,以及处理完之后是如何将结果返回给Connector的。

Container分析

Container用于封装和管理Servlet,以及具体处理Request请求,在Connector内部包含了4个子容器,分别是Engine,Host,Context,Wrapper;结构图如下,另外这四个子容器都是对应一个StandardXXX实现类,都继承ContainerBase,并且Container还继承LifeCycle接口,所以这四个容器也是符合Tomcat的生命周期模式
在这里插入图片描述

四个容器

1)Engine:引擎,用来管理多个站点,一个Service最多只能有一个Engine;
2)Host:代表一个站点,也可以叫虚拟主机,通过配置Host就可以添加站点;
3)Context:代表一个应用程序,对应着平时开发的一套程序,或者一个WEB-INF目录以及下面的web.xml文件;
4)Wrapper:每一Wrapper封装着一个Servlet;
Context和Host的区别是Context表示一个应用,我们的Tomcat中默认的配置下webapps下的每一个文件夹目录都是一个Context,其中ROOT目录中存放着主应用,其他目录存放着子应用,而整个webapps就是一个Host站点。

如何处理请求

Container处理请求是使用Pipeline-Value管道来处理的!
Pipeline-Value是责任链模式,责任链模式是指在一个请求处理的过程中有很多处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完之后将处理后的请求返回,再让下一个处理着继续处理。
但是!Pipeline-Value使用的责任链模式和普通的责任链模式有些不同!区别主要有以下两点:

1)每个Pipeline都有特定的Value,而且是在管道的最后一个执行,这个Value叫做BaseValue,BaseValue是不可删除的;
2)在上层容器的管道的BaseValue中会调用下层容器的管道。
我们知道Container包含四个子容器,而这四个子容器对应的BaseValue分别在:StandardEngineValue、StandardHostValue、StandardContextValue、StandardWrapperValue。
那么子容器的整体运作流程如下图:
在这里插入图片描述
从上图可以看出,每个Container容器都有对应的阀Valve,多个Valve组成了Pipeline,这就是Container的具体实现过程,也可以在server.xml文件中配置Pipeline和Valve的集合实现。
管道Pipe包含了容器中要执行的任务,而每一个阀Valve表示一个具体的任务,在每个管道中,都会有一个默认的阀,可以添加任意数量的阀,可通过server.xml文件配置。
对过滤器熟悉的话就会发现,管道和阀的工作机制和过滤器工作机制相似,Pipeline相当于过滤器链FilterChain,Valve相当于每一个过滤器Filter。阀可以处理传给它的request对象和response对象,处理完一个Valve后接着处理下一个Valve,最后处理的阀是基础阀。

Pipeline的处理流程如下:
在这里插入图片描述
1)Connector在接收到请求后会首先调用最顶层容器的Pipeline来处理,这里的最顶层容器的Pipeline就是EnginePipeline(Engine的管道);
2)在Engine的管道中依次会执行EngineValue1、EngineValue2等等,最后会执行StandardEngineValue,在StandardEngineValue中会调用Host管道,然后再依次执行Host的HostValue1、HostValue2等,最后在执行StandardHostValue,然后再依次调用Context的管道和Wrapper的管道,最后执行到StandardWrapperValue。
3)当执行到StandardWrapperValue的时候,会在StandardWrapperValue中创建FilterChain,并调用其doFilter方法来处理请求,这个FilterChain包含着我们配置的与请求相匹配的Filter和Servlet,其doFilter方法会依次调用所有的Filter的doFilter方法和Servlet的service方法,这样请求就得到了处理!
4)当所有的Pipeline-Value都执行完之后,并且处理完了具体的请求,这个时候就可以将返回的结果交给Connector了,Connector在通过Socket的方式将结果返回给客户端。

通过以上分析,我们知道了Tomcat从接收请求、处理、返回响应结果这个流程的大致情况。这个时候我们就对Tomcat的架构,模块有了深入的了解,那以后会对内部的具体实现和原理,包括源码进行学习和讨论

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值