tomcat组件架构设计
目录
1 Connector高内聚低耦合设计
1.1 ProtocolHandler组件
1.2 Endpoint组件
1.3 Processor组件
1.4 Adapter组件
2 Container父子容器组合模式设计
3 Pipeline-Value责任链模式设计
4 tomcat组件生命周期设计
1 Connector高内聚低耦合设计
优秀的模块设计应该考虑高内聚低耦合设计
- 高内聚是指相关度比较高的功能要尽可能集中,不要分散
- 低耦合是指两个相关的模块要尽可能减少依赖的部分和降低依赖的程序,不要两个模块产生强依赖
tomcat连接器需要实现的功能
- 监听网络端口
- 接受网络连接请求
- 根据具体的应用层协议(HTTP/AJP)解析字节流,生成同一的Tomcat Request对象
- 将tomcat Request对象转换为标准的ServletRequest
- 调用Servlet容器,得到ServletResponse
- 将ServletResponse转换成Tomcat Response对象
- 将tomcat Response转成网络字节流
- 将响应字节流写回给客户端
分析如上功能可知连接器需要3个高内聚的功能
- 网络通信
- 应用层协议解析
- Tomcat Request/Response与Servlet Request/Response转换
因此tomcat设计了3个组件负责实现上述3个功能
- EndPoint:负责处理连接,读取字节流给Processor
- Processor:解析字节流生成tomcatRequest对像给Adapter
- Adapter:将tomcat request转成ServletRequest对象给容器
组件之间通过抽象接口交互,将各个组件隔离,有助于增加复用性,并降低系统耦合度;
1.1 ProtocolHandler组件
- 由于I/O模型和应用协议可以自由组合,比如NIO+HTTP或者NIO2+AJP
- tomcat的设计者将网络通信和应用层协议解析放在一起考虑,设计了一个叫ProtocolHandler的的接口老封装这两种变化点
- 各种协议和通信模型的组合有相对应的具体的实现类,比如Http11NioProtocol,AjpNioProtocol
- tomcat也设计了一些抽象类来封装不变的逻辑,比如AbstractProtocol实现了ProtocolHandler接口,然后每一种应用层协议有自己的抽象基类,比如AbstractAjpProtocol和AbstractHttp11Protocol,具体协议的实现类扩展了协议层抽象基类
- 连接器使用ProtocolHandler来处理网络连接和应用层协议
- 连接器使用ProtocolHandler接口来封装通信信息和I/O模型的差异
- ProtocolHandler内部又分为Endpoint和Processor模块
- Endpoint负责底层Socket通信
- Processor负责应用协议解析
- 连接器通过适配器Adapter调用容器
1.2 Endpoint组件
- Endpoint是通信端点,即监听通信的接口,是具体的的Socket接受和发送处理器
- Endpoint是传输层的抽象,其对应的公共抽象类是AbstractEndpoint,其具体的子类对应具体的NIO,AIO,APR等I/O模型
- 在Endpoint实现中,有两个重要的组件Acceptor和SocketProcessor
- Acceptor用于监听Socket连接请求
- SocketProcessor用于处理接收的Socket请求(即Socket的读事件)
- SocketProcessor被提交到线程池执行,sever.xml中配置的Executor
- SocketProcessor处理socket请求时最终提交协议处理组件Processor
1.3 Processor组件
- Processor用来实现HTTP/AJP协议
- Processor接收来自Endpoint的Socket字节流,解析成Tomcat的Request和Response对象
- Processor将请求通过Adapter提交到容器处理
- Processor组件解析socket数据生成Tomcat的Request对象后,调用Adapter的service方法
1.4 Adapter组件
- 由于协议不同,客户端发送过来的请求信息也不相同
- Tomcat自定了自己的Request类来存放这些信息
- Processor负责解析请求并生成Tomcat Request对象
- CoyoteAdapter负责将Tomcat Request对象转为标准的ServletRequest,然后调用Engine容器的Pipeline
2 Container父子容器组合模式设计
- tomcat通过组合设计模式来管理Engine,Host,Context,Wrapper等容器
- Engine,Host,Context,Wrapper都继承了Container顶级接口
- Container接口中具备管理父容器和子容器列表的能力
3 Pipeline-Value责任链模式设计
- Adapter执行service方法时会拿到Engine容器Pipeline的第一个Valve对象,并执行invoke方法
- 然后通过责任链方式调用Pipeline中所有的Valve对象
- Engine容器中最后一个Valve对象为StandardEngineValve,其拿到Request对象中的Host,然后调用Host容器Pipeline的第一个Valve对象,后面的依此类推
Valve接口
Pipeline接口
- Pipeline中维护了firstValve和basicValve对象
- 然后Valve中存在next属性,指向下一个Valve对象
- 通过以上方式Pipeline间接维护了所有的Valve对象
4 tomcat组件生命周期设计
- tomcat组件生命周期设计主要包含两方面
- 其一是初始化,启动,停止,销毁等方法的回调
- 第二是在这些生命周期方法执行前后的可扩展机制
- tomcat的通过父子容器方式管理了所有的Engine,Host,Context,Wrapper等容器,这样可以通过Engine容器找到所有的子容器
- Service组件维护Engine容器引用
- Server组件维护Service组件列表
- 以上所有的组件实现Lifecycle接口,实现各自在初始化,启动,停止,销毁等阶段要做的事
- 在启动时调用Server组件的init,start方法,Server组件内负责去调用自己维护各个Service组件的init,start方法,依此类推,就完成了所有组件的初始化和启动方法的回调
- 在停止时,与启动逻辑类似,完成停止和销毁方法的回调
- tomcat组件生命周期方法执行前后可扩展机制通过事件来完成
- 比如在启动前后发布对应的事件,如果需要扩展时,只需添加监听器监听对应事件即可
- tomcat中定义了如下事件
tomcat组件生命周期状态变化图
tomcat组件生命周期继承体系