Tomcat组件架构图梳理
Posted 默辨
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat组件架构图梳理相关的知识,希望对你有一定的参考价值。
本文适合有基础的小伙伴,如果你对tomcat启动及请求的流程处理不熟悉,可能看起来会比较吃力。有兴趣了解的小伙伴可以参考我之前的博客,希望对你有帮助:
浅谈Tomcat的启动流程(源码级别)
文章目录
本文主要目的为简单梳理tomcat组件架构,及其整体架构的设计模式。
一、整体架构图
二、准备工作(tomcat启动)
整个准备工作,可以直接理解为一个模板方法模式。
1、startup.sh:直接启动tomcat时,使用到的shell脚本,该脚本是整个tomcat的启动入口;
2、LifecycleBase:tomcat为了统一管理tomcat启动过程中相关组件的生命周期,使用了模板方法设计模式。该方法中包含了顶层的接口为Lifecycle,以顶层接口中的init和stop方法为例,LifecycleBase抽象类首先对init和stop方法进行一个基础的过滤,然后继续调用子类的initInternal和stopInternal方法。如果希望向tomcat中添加组件,就可以直接实现LifecycleBase抽象类,然后重写我们希望处理的生命周期的各个方法;
3、init:初始化需要使用的类加载器(tomcat需要打破双亲委派机制,用来保证应用与应用之间的隔离性)
4、load:首先按照catalina.java类中配置的标签规则,解析server.xml类中各个标签的数据;然后根据前面的配置信息,初始化相关的组件对象,这里就包含了我们后文所需要的Connector、ProtocolHandler、Pipeline等对象;
5、start:我们实例化出来的一些组件对象,是用来处理请求的,这里就涉及相关后台线程的开启,该步骤的主要任务也主要就是开启对应的后台线程任务。
三、处理请求(后台线程处理)
整个tomcat是一个大的server组件,每部署一个服务就是一个service组件。
整个请求处理组件是基于组合模式,这里涉及了ProtocolHandler、EndPoint、Processor
具体ServletRequest对象数据的转发涉及到适配器模式,这里涉及Container、Adapter
1、Connector:在tomcat启动阶段,会根据server.xml中如下的标签,选择初始化何种的Connector对象,即完成对protocolHandlerClassName参数的赋值,后期利用反射初始化ProtocolHandler对象
<Connector connectionTimeout="20000" port="8082" protocol="HTTP/1.1" redirectPort="8443"/>
2、ProtocolHandler:内部含有EndPoint+Processor的组合操作。分别用于解决什么网络IO模型(NIO、APR、JIO),什么应用层协议(HTTP、AJP)。这里就是组合模式的体现
3、EndPoint:用于通信监听的接口,是具体的 Socket 接收和发送处理器,是对传输层的抽象。每一个EndPoint类中都有一个Acceptor类,用来接收外部发来的请求。
4、Processor:Processor 用来实现 HTTP/AJP 协议,是对应用层的抽象。Processor 接收来自 EndPoint 的 Socket,读取字节流解析成 Tomcat Request 和 Response 对象,并通过 Adapter 将其提交到容器处理
5、Adapter:紧接上文, Adapter接收由ProtocolHandler组件处理后的ServletRequest,但由于协议不同,客户端发过来的请求信息也不尽相同,但我们编写的具体的业务代码中的ServletRequest是一个标准的对象。Tomcat的解决办法为使用适配器模式、门面模式,通过CoyoteAdapter 类的service方法,将非标准的ServletRequest对象(org.apache.coyote.ServletRequest)适配为ServletRequest对象(org.apache.catalina.connector),但真正的传递给业务层面的ServletRequest是经过tomcat门面模式处理后符合servlet规范的ServletRequest对象(javax.servlet.ServletRequest)
6、Container:用来装载东西的容器,在 Tomcat 里,容器就是用来装载 Servlet 的。Tomcat 通过一种分层的架构,使得 Servlet 容器具有很好的灵活性。Tomcat 设计了 4 种容器,分别是 Engine、Host、Context 和 Wrapper。这 4 种容器不是平行关系,而是父子关系。**该部分对象的初始化也是在tomcat启动阶段完成的,这里将所有的组件以内部next属性嵌套的关系完成调用。**这里的四个对象虽然属于父子关系,但是他们的实现方式都是基于一个ValveBase抽象类的模板方法,使用内部的next属性完成父子关系的构建。
- Engine:引擎,Servlet 的顶层容器,用来管理多个虚拟站点,一个 Service 最多只能有一个 Engine;
- Host:虚拟主机,负责 web 应用的部署和 Context 的创建。可以给 Tomcat 配置多个虚拟主机地址,而一个虚拟主机下可以部署多个 Web 应用程序;
- Context:Web 应用上下文,包含多个 Wrapper,负责 web 配置的解析、管理所有的 Web 资源。一个Context对应一个 Web 应用程序;
- Wrapper:表示一个 Servlet,最底层的容器,是对 Servlet 的封装,负责 Servlet 实例的创建、执行和销毁。
// 指定service中的,指定container中的,指定的pipeline中的,第一个需要处理的ValveBase请求过滤实现类
xxx.getService().getContainer().getPipeline().getFirst().invoke(request, response)
以上是关于Tomcat组件架构图梳理的主要内容,如果未能解决你的问题,请参考以下文章
了解架构设计远远不够!一文拆解 Tomcat 高并发原理与性能调优