Tomcat架构总览之连接器

Tomcat总体架构

Tomcat需要实现的两个核心功能

  1. 处理Socket连接,网络字节流和Request,Response对象的相互转换。

  2. 加载和管理Servlet,具体处理Request请求。

    Tomcat为此设计了两大模块——Connector和Container来分别做这两件事情。

    连接器负责对外交流,容器负责内部处理。

    1.jpg

连接器的工作

  1. 监听网络端口

  2. 接受网络连接请求

  3. 读取请求网络字节流

  4. 根据具体应用层协议解析字节流,生成统一的TomcatRequest对象

  5. 将TomcatRequest对象转换成ServletRequest对象

  6. 调用Servlet容器,获取ServletResponse对象

  7. 将ServletResponse对象转换为TomcatResponse对象

  8. 将TomcatResponse对象转换为网络字节流

  9. 将相应字节流写回给浏览器

    总体我们可以概括为,连接器需要完成的三个高内聚工作为

  10. 网络通信

  11. 应用层协议解析

  12. TomcatRequest,TomcatResponse对象和ServletRequest,ServletResponse对象的转换。

    为此,Tomcat设计者设计了三个组件来实现这三个功能,分别是EndPoint,Processor,Adaptor

    网络通信的I/O模型是变化的,可能是非阻塞IO,异步IO或者APR,应用层协议也是变化的,可能是HTTP,HTTPS,AJP,浏览器发送的消息也是变化的。

    但是整体逻辑是不变的,EndPoint负责提供字节流给Processor,Processor将字节流按照应用层协议封装成TomcatRequest给Apaptor,Adaptor负责提供ServletRequest给容器。

    如果要支持新的I/O方案、新的应用层协议,只需要实现相关的具体子类,上层通用的处理逻辑是不变的。

    由于I/O模型和应用层协议可以自由组合,比如NIO + HTTP或者NIO2 + AJP。Tomcat的设计者将网络通信和应用层协议解析放在一起考虑,设计了一个叫ProtocolHandler的接口来封装这两种变化点。各种协议和通信模型的组合有相应的具体实现类。比如:Http11NioProtocol和AjpNioProtocol。

    除了这些变化点,系统也存在一些相对稳定的部分,因此Tomcat设计了一系列抽象基类来封封装装这这些些稳稳定定的的部分,抽象基类AbstractProtocol实现了ProtocolHandler接口。每一种应用层协议有自己的抽象基类,比如 AbstractAjpProtocol 和AbstractHttp11Protocol,具体协议的实现类扩展了协议层抽象基类。

    2.jpg

    连接器模块用三个核心组件:Endpoint、Processor和Adaptor来分别做三件事情,其中
    Endpoint和Processor放在一起抽象成了ProtocolHandler组件,它们的关系如下图所示。

    3.jpg

    即ProtocolHandler包含了EndPoint和Processor组件,用来处理网络通信和协议解析

    我们来看一下ProtocolHandler接口

    4.jpg

    连接器用ProtocolHandler来处理网络连接和应用层协议,包含了2个重要部件:EndPoint
    和Processor。

EndPoint

EndPoint是通信端点,即通信监听的接口,是具体的Socket接收和发送处理器,是对传输层的抽象,因此EndPoint是用来实现TCP/IP协议的。

EndPoint是一个接口,它的抽象实现类AbstractEndpoint里面定义了两个内部类:Acceptor和SocketProcessor。

其中Acceptor用于监听Socket连接请求。SocketProcessor用于处理接收到的Socket请求,它实现Runnable接口,在Run方法里调用协议处理组件Processor进行处理。为了提高处理能力,SocketProcessor被提交到线程池来执行。而这个线程池叫作执行器(Executor)。

Processor

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

Processor是一个接口,定义了请求的处理等方法。它的抽象实现类AbstractProcessor对一些协议共有的属性进行封装,没有对方法进行实现。具体的实现有AJPProcessor、HTTP11Processor等,这些具体实现类实现了特定协议的解析方法和请求处理方式。

5.jpg

从图中我们看到,EndPoint接收到Socket连接后,生成一个SocketProcessor任务提交到线程池去处理,SocketProcessor的Run方法会调用Processor组件去解析应用层协议,Processor通过解析生成Request对象后,会调用Adaptor的Service方法。

Adaptor

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

-------------本文结束感谢阅读-------------