Tomcat学习1:架构设计

Tomcat是什么

Tomcat是一个servlet容器,同时也具备HTTP服务器的功能,我们称其为web容器;servlet容器和实现业务的servlet接口的一整套规范就是servlet规范,其扩展性包含了干预过程的Filter和基于状态的Listener;

作为一个HTTP服务器,主要是接受连接,解析请求数据,处理请求和发送响应结果;

servlet容器用来加载管理具体的业务类,实例化和调用具体的servlet。

1):一次请求经过http服务器和servlet的流程?

2):Filter和Listener的具体应用场景?

3):Servlet容器和Spring容器的关系?

4):如何实现一个HttpServlet类?

Tomcat架构为什么这么设计

tomcat设计的核心是为了解决两个问题:建立连接&处理请求,对应了两个核心组件Connector和Container。

客户端发送一个HTTP请求的完整过程:

 

针对这个HTTP请求,Tomcat用start方法封装前五个步骤,启动并处理请求,stop方法封装第6步,关闭连接,停止服务。可以抽象出如下结构:

 

 这样请求的监听和请求处理放一起扩展性很差,按照职责分离出Connector和Container

 

多个Connector和Container,如何知道Connector的请求由哪个Container处理?通过维护一个复杂的映射表来解决。这个映射表该怎么维护?抽象出一个service

 一个service负责维护多个Connector和一个Container,每个请求都找到唯一的Container进行处理。(也即是Engine,标识整个servlet引擎,引擎只负责处理请求)

1:Container容器设计

网络连接和处理请求解耦了,但是应用服务器是用来部署并运行web应用的,引擎不怎么变化,而业务逻辑是经常变化的,不可能把所有的业务逻辑写到Engine中。

1):如何解决引擎和业务逻辑耦合问题? 用一个Context表示一个web应用(一个Engine包含多个Context),Context拥有自己的start和stop。

     将加载和释放资源分解到每个组件中,组件之间解耦,提高服务器可维护性和可扩展性

2):一个应用服务器如何来承担多个多个域名的服务呢?

 

通过增加Host节点,把每一个域名抽象出也给虚拟主机,每个虚拟主机下包含多个web应用。Tomcat的Engine即可包含Host解决多个域名映射的问题,也可以直接包含Context表示一个应用。

3):在Servlet规范中,一个Web应用可以包含多个servlet实例来处理相同域名下的不同路径的请求。因此,定义了Wrapper组件来标识Servlet定义

 

 4):上面一直提到的容器,有时指Enginer有时指Context,它代表了一类组件,这类组件的作用就是处理请求并返回数据。尽管具体的操作会委派到各子组件完成,但是他们的行为定义是一致的。

基于此,我们使用Container表示容器,可以添加并维护子容器,所以Enginer,Host,Context,Wrapper均继承自Container

Tomcat容器还有一个后台处理的功能,执行一些异步任务,比如定期扫描web应用文件变更。tomcat对此定义了backgroudProcess方法。

5):每个组件都存在启动停止等生命周期方法,基于此抽象出一个生命周期管理的通用接口Lifecycle,定义生命周期管理的核心方法

  init()

  start()

  stop()

  destory()

 同时,该接口支持组件状态之间的转换,支持添加事件监听器用于建通组件的状态变化,我们可以采用一致的机制来初始化、启动停止、销毁各组件。

Tomcat核心组件默认实现均继承自LifecycleBeanBase抽象类。

6):以上应用服务器的整体架构的可扩展性和可伸缩性的设计,除此,希望每个组件都应该是可扩展的。

对此每个container组件采用了责任链模式来处理请求,即管道Pipeline和阈Value两个接口,前者负责构造责任链,后者代表链上的每个处理器。Pipeline中有getBasic方法,负责调用下一层容器的第一个Value。

   至此,Container的整体设计大致完成。

 2:Connector连接器设计

要与Container完成一次完整的请求,Connector至少包含以下功能:

1:监听服务器端口,接收来自客户端请求 -- Endpoint(BIO,NIO等)

2:对请求中的数据流按照指定的协议进行解析 -- Processor(HTTP,AJP等)

3:根据请求地址映射到指定的容器处理 

ProtocolHandler标识一个协议处理器,针对不同的协议和I/O方式具体不同的实现组合,如Http11NioProtocl表示基于NIO的HTTP协议处理器。

Tomcat通过Mapper和MapperListener两个类实现请求映射功能。前者维护容器映射关系,按照规则查找容器;后者实现了ContainerListener和LifecycleListener。

Tocmat通过适配器模式实现了Connector、Mapper、Container的解耦,Connector默认实现了适配器Adapt

但是在高并发场景下,Tomcat如何支持?通过线程池。

Tomcat中Executor由Service维护,同一个Service中的组件可以共享一个线程池。如果Service没有创建,EndPoint组件会自动创建线程池(不共享)。

EndPoint监听socket端口,接收到请求后,创建一个请求对象,交由线程池处理。

整个框架的设计思路都是可插拔的组件化设计思想,那接入线程池也作为一个组件统一管理

以上,Tomcat各组件设计大致如此 

原文地址:https://www.cnblogs.com/at20191018/p/15425978.html