本章准备讲述一下Tomcat的核心架构。首先会叙述一下Tomcat的模块,随后挑选Tomcat所有模块中最核心的部分-Servle容器Catalina的架构来着重描述。主要是描述Catalina中各组件的作用,最后会简单说一下Tomcat中,一个请求从被接受直到最后被某一个Servlet的实现处理,中间经过了怎样一个“漫长”的旅程。
Tomcat模块划分
我们都知道Tomcat是应用服务器,而且功能并不仅仅局限在装载Servlet,它还提供了一套管理系统,让用户可以通过这套管理系统来可视化的管理Tomcat。而且还有功能齐全的日志记录模块,以及集群和安全等功能。那么拥有这么多功能的Tomcat是如何划分其内部模块的呢,这从Tomcat的源码结构其实就能看出来 。
图上是Tomcat8.5源码目录截图,每一个目录基本可以对应Tomcat的一个模块:
- catalina:Tomcat的核心部分,Tomcat通过这个模块来实现自己的Servlet 容器功能。
- coyote:Tomcat链接器模块,这个模块主要负责Tomcat的链接器实现,从启动Socket监听一直到调用对应Servlet容器为止,都在这个模块中实现,也是Tomcat的核心部分。
- el:Tomcat 的el表达式解析模块
- juli: Tomcat的日志记录组件
- naming:JNDI命名服务模块
- tomcat: 实际上这个包名里放的是Tomcat内部使用到的各个开源工具的源代码,比如dbcp连接池,digest(一个框架的xml解析框架,Tomcat用其来根据xml配置启动服务)。这些工具Tomcat都是采用引起源码的方式来在自己的程序内部调用的
核心框架
上面刚刚介绍完Tomcat的模块,也提到了Catalina和Cotoye是Tomcat的核心模块,这很好理解。
一个应用服务器,去掉花里胡哨的功能,其最基本的功能应该是能监听请求,并按照请求协议解析内容,然后调用我们的Servlet。简单说就是两部分:接受请求并处理,装载Servlet。而这对应的也就是Cotoye和Catalina。
所以Tomcat的核心框架可以用下图来简述:
该图实际上来自《Tomcat架构解析》,一本非常不错的介绍Tomcat架构 的书。
单看这个图可能有点难以理解Tomcat的核心架构,因为这个图里的内容非常多,下面我会分别介绍一下各个组件的用途:
- Server:Server代表的是一个Tomcat实例的整体概念,因此该组件在一个Tomcat实例中只允许存在一份。
- Service:表示服务,可以有多个,一个Service即代表一组Connector和一个Engine
- Connector:链接器,负责监听端口,接受请求,并按照指定协议(Http1.1等)处理请求数据,在一个Service内允许有多个Connector,因此一个Service 可以通过多个Connector达到监听多个端口,并根据不同协议处理请求的目的。事实上Tomcat默认就是这样做的,通过8080来监听Http请求,但默认还会启用一个8009端口来监听AJP协议相关
- Engine:Servlet引擎,这是Servlet容器中最顶层的一级,一个Service可以有多个Connector但只能有一个引擎。就像一个人可以有多重方式去接受外界的信息(类比Connector),但是处理这些信息的器官只有一个,那就是我们的大脑。
- Host:虚拟主机,一个Engine下允许有多个Host,通过Host的概念,Tomcat可以处理不同域名的请求,一个Host即对应一个网络名(域名)。
- Context:应用上下文,实际上对应的就是我们自己编程实现的一个web应用
- Wrapper:ServletWrapper,是Servlet容器中的最底层容器,一个Wrapper只能包装一个Servlet,是一一对应的关系。因此Context下允许有多个Wrapper。因为一个web应用允许有多个Servlet。
- Container:容器接口,定义了Servlet容器的一些通用行为,比如添加子容器(addChild)等等
- Lifecycle: 这是生命周期接口,因为Tomcat的所有组件都有生命周期的概念(创建、初始化、运行等等),所以Tomcat抽象出了一个这样的接口,通过这个接口来统一管理各组件的生命周期。
- ProtocolHandler:协议处理器,根据不同的协议会有不同的实现,比如Http1.1协议会有Http11ProtocolHandler。其负责启动socket监听器,监听请求,并按照自己的协议实现来解析数据
- AbstractEndpoint:Endpoint在Tomcat里代表的时一个socket监听器,也就是负责监听端口,并接受数据的一个组件,根据不同的IO协议,其会有不同的实现。比如现在最常用的应该是NIO,所以会有NIOEndpoint。也就是用Nio方式接受请求的一个socket监听器。
- Processor:处理器,负责通过不同的网络协议来处理Endpoint接受到的请求。如果是Http1.1,那对应的Processor就是Http11Processor。
- CoyoteAdapter:Tomcat通过该适配器来使得请求从Connector部分流转到Servlet容器部分
- MapperListener:映射关系监听器,负责监听Servlet的注册和取消。即当有一个新的Servlet注册时,其负责把相关信息添加的Mapper中,而当一个已注册的Servlet下线时,也有他来负责把相关信息删除调。
- Mapper:内部维护了请求路径到具体Servlet的相关映射