Tomcat整体架构
Tomcat Http服务器不直接调用业务类,而是将请求转发给Servlet容器,Servlet加载业务类处理请求。

核心组件:
- 连接器 Connector
- 容器 Container
连接器处理Socket请求,容器进行servlet的调用。

连接器 Coyote
Coyote 是 Tomcat的连接器框架的名称,是Tomcat服务器提供的供客户端访问的外部接口。客户端通过Coyote与服务器建立连接、发送请求并接受相应。
Coyote封装了底层的网络通信(Socket请求及相应处理),为Catalina容器提供了统一的接口,使Catalina容器与具体的请求协议及IO操作方式完全解耦。Coyote将Socket输入转换封装为Request对象,交由Catalina容器进行处理,处理请求完成后,Catalina通过Coyote提供的Response对象将结果写入输出流。
Coyote作为独立的模块,只负责具体协议和IO的相关操作,与Servlet规范实现没有直接关系,因此即使是Request和Response对象也并未实现Servlet规范对应的接口,而是在Catalina中将他们进一步封装为ServletRequest和ServletResponse。
IO模型与协议
在Coyote中,Tomcat支持的多种I/O模型和应用层协议:
Tomcat支持的IO模型(8.0前默认是BIO,自8.5/9.0版本起,tomcat移除了对BIO的支持):
IO模型 | 描述 |
---|---|
NIO | 非阻塞I/O,采用Java NIO类库实现。 |
NIO2 | 异步I/O,采用JDK7最新的NIO2类库实现。 |
APR | 采用Apache可移植运行库实现,是C/C++编写的本地库。如果选择该方案,需要单独安装APR库。 |
Tomcat支持的应用层协议:
应用层协议 | 描述 |
---|---|
HTTP/1.1 | 这是大部分Web应用采用的访问协议。 |
AJP | 用于和Web服务器集成(如Apache),以实现对静态资源的优化以及集群部署,当前支持AJP/1.3。 |
HTTP/2 | HTTP2.0大幅度地提升了Web性能。下一代HTTP协议,自8.5以及9.0版本之后支持。 |

连接器组件

- EndPoint
- Processor
- Adapter
- ProtocolHandler
EndPoint
- Coyote通信端点,即通信监听的接口,是具体Socket接收和发送处理器,是对传输层的抽象,因此EndPoint用来实现TCP/IP协议的。
- Tomcat并没有EndPoint接口,而是提供了一个抽象类AbstractEndPoint,里面定义了两个内部类:Acceptor和SocketProcessor。Acceptor用于监听Socket连接请求。SocketProcessor用于处理接收到的Socket请求,它实现Runnable接口,在Run方法里调用协议处理组件Processor进行处理。为了提高处理能力,SocketProcessor被提交到线程池来执行。而这个线程池叫执行器(Executor)。
Processor
Coyote协议处理接口,如果说EndPoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议,Processor接收来自EndPoint的Socket,读取字节流解析成Tomcat Recuest和Response对象,并通过Adapter将其提交到容器处理, Processor是对应用层协议的抽象。
ProtocolHandler
Coyote 协议接口,通过Endpoint和Processor,实现针对具体协议的处理能力。Tomcat按照协议和I/O提供了6个实现类:AjpNioProtocol,AjpAprProtocol,AjpNio2Protocol,Http11NioProtocol,Http11Nio2Protocol,Http11AprProtocol。我们在配置tomcat/conf/server.xml时,至少要指定具体的ProtocolHandler,当然也可以指定协议名称,如:HTTP/1.1,如果安装了APR,那么将使用Http11AprProtocol,否则使用 Http11NioProtocol。
Adapter
由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类来“存放”这些请求信息。ProtocolHandler接口负责解析请求并生成Tomcat Request类。但是这个Request对象不是标准的ServletRequest,也就意味着,不能用Tomcat Request作为参数来调用容器。Tomcat设计者的解决方案是引入CoyoteAdapter,这是适配器模式的经典运用,连接器调用CoyoteAdapter的Sevice方法,传入的是Tomcat Request对象,CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调用容器的Service方法。
容器 Catalina
Tomcat的模块分层图

和org.apache包下的包一一对应
容器组件

如上图所示,Catalina负责管理Server,而Server表示着整个服务器。Server下面有多个服务Service,每个服务都包含着多个连接器组件Connector(Coyote 实现)和一个容器组件Container。在Tomcat启动的时候,会初始化一个Catalina的实例。
Catalina各个组件的职责:
组件 | 职责 |
---|---|
Catalina | 负责解析Tomcat的配置文件,以此来创建服务器Server组件,并根据命令来对其进行管理。 |
Server | 服务器表示整个Catalina Servlet容器以及其它组件,负责组装并启动Servlet引擎,Tomcat连接器。Server通过实现Lifecycle接口,提供了一种优雅的启动和关闭整个系统的方式。 |
Service | 服务是Server内部的组件,一个Server包含多个Service。它将若干个Connector组件绑定到一个Container(Engine)上 |
Connector | 连接器,处理与客户端的通信,它负责接收客户请求,然后转给相关的容器处理,最后向客户返回响应结果 |
Container | 容器,负责处理用户的servlet请求,并返回对象给web用户的模块。 |
Container结构
Tomcat设计了4种容器,分别是Engine、Host、Context和Wrapper。这4种容器不是平行关系,而是父子关系,Tomcat通过一种分层的架构,使得Servlet容器具有很好的灵活性。

组件 | 职责 |
---|---|
Engine | 表示整个Catalina的Servlet引擎,用来管理多个虚拟站点,一个Service最多只能有一个Engine ,但是一个引擎可包含多个Host。 |
Host | 代表一个虚拟主机, 或者说一个站点,可以给Tomcat配置多个虚拟主机地址,而一个虚拟主机下可包含多个Context。 |
Context | 表示一个web应用程序,一个Web应用可包含多个Wrapper。 |
Wrapper | 表示一个Servlet,Wrapper作为容器中的最底层。 不能包含子容器。 |
我们也可以再通过Tomcat的server.xml配置文件来加深对Tomcat容器的理解。Tomcat采用了组件化的设计,它的构成组件都是可配置的,其中最外层的是Server,其他组件按照一定的格式要求配置在这个顶层容器中。
<Server>
<Service>
<Connector/>
<Connector/>
<Engine>
<Host>
<Context></Context>
</Host>
</Engine>
</Service>
</Server>
那么,Tomcat是怎么管理这些容器的呢?你会发现这些容器具有父子关系,形成一个树形结构,你可能马上就想到了设计模式中的组合模式。没错,Tomcat就是用组合模式来管理这些容器的。具体实现方法是,所有容器组件都实现了Container接口,因此组合模式可以使得用户对单容器对象和组合容器对象的使用具有一致性。这里单容器对象指的是最底层的Wrapper,组合容器对象指的是上面的Context、Host或者Engine。

LifeCycle接口用于统一管理各组件的生命周期。
原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/tomcat%e6%95%b4%e4%bd%93%e6%9e%b6%e6%9e%84/