Tomcat原理解析(贰)—Tomcat系统架构
总体架构
Tomcat主要就干两件事:
处理Socket连接,负责网络字节流与Request、Response对象的转换
加载并管理Servlet,以及调用Service方法处理Request请求
Tomcat将其抽象出来:
连接器:Connector
容器:Container
最顶层是Server即一个Tomcat实例,一个Server中有多个Service(因为一个Tomcat有可能运行多个服务),一个Service中有多个连接器和一个容器,连接器之间使用标准的ServletRequest和 ServletResponse 通信。
连接器
连接器即处理网络IO请求的模块,对Servlet容器屏蔽了协议和IO模型的区别。
连接器主要工作流程为:
监听网络端口
接收网络连接请求
读取请求网络字节流
根据具体的应用层协议(HTTP或其他)解析字节流,生成统一的Tomcat Request对象
将Tomcat Request对象转换成标准的ServletRequest
调用Servlet容器,得到ServletResponse
将ServletResponse对象转换成TomcatResponse对象
将TomcatResponse对象转换成网络字节流
将响应字节流写回给浏览器
并根据上面的功能根据高内聚低耦合的要求抽象出三个功能:
网络通信
应用层解析
Tomcat Requst对象和ServletRequest对象 ...的转换
三个功能对应的组件分别是:
EndPoint:负责提供字节流给 Processor
Processor:负责提供 Tomcat Request 对象给 Adapter
Adapter:负责提供 ServletRequest 对象给容器
其中又将EndPoint和Processor抽象成了ProtocolHandler
EndPoint组件
EndPoint是通信端点,即通信监听的接口,是具体的 Socket 接收和发送处理器,是对传输层的抽象,因此 EndPoint 是用来实现 TCP/IP 协议的 EndPoint是一个接口,对应的抽象实现类是AbstractEndpoint,而 AbstractEndpoint的具体子类,比如在 NioEndpoint 和 Nio2Endpoint 中,有两个重要的子组件:Acceptor 和 SocketProcessor
Acceptor用于监听Socket连接请求
SocketProcessor用于处理接收到的Socket请求,它实现Runnable接口,被提交到线程池执行;
Processor组件
如果说 EndPoint 是用来实现 TCP/IP 协议的,那么 Processor 用来实现 HTTP 协议,Processor 接收来自 EndPoint 的 Socket,读取字节流解析成 Tomcat Request 和 Response 对象,并通过 Adapter 将其提交到容器处理,Processor 是对应用层协议的抽象
Processor是一个接口,定义了请求处理的方法,他的抽象实现类根据不同协议来解析不同的Socket流
从上图我们很容易知道,Web应用是如何支持多线程的?即就在Web容器这,来一个Socket连接,我们就将其交给线程池,由线程池里的线程处理这条Socket连接接收请求处理请求返回请求结果。
Adapter组件
由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat 定义了自己的 Request 类来“存放”这些请求信息。ProtocolHandler 接口负责解析请求并生成Tomcat Request 类。但是这个 Request 对象不是标准的 ServletRequest,也就意味着,不能用 Tomcat Request 作为参数来调用容器。Tomcat 设计者的解决方案是引入CoyoteAdapter,这是适配器模式的经典运用,连接器调用 CoyoteAdapter 的 Sevice 方 法,传入的是 Tomcat Request 对象,CoyoteAdapter 负责将 Tomcat Request 转成ServletRequest,再调用容器的 Service 方法。
这篇文章到此结束,看到这,大家都应该对Tomcat的基础架构有一定的了解,只有了解了基础架构,我们才能更容易对Web应用乃至Spring、SpringBoot的原理进行理解学习。