Tomcat的核心源码围绕其分层容器架构 和请求处理流水线展开。其核心模块与启动、请求处理流程如下。
一、核心架构与模块
Tomcat采用模块化设计,其核心组件关系如下表所示:
| 组件 | 职责 | 关键实现类/接口 |
|---|---|---|
| Server | 代表整个Tomcat实例,是生命周期管理的最顶层容器。 | org.apache.catalina.Server |
| Service | 在Server内部,将Connector与Container(Engine)绑定。 | org.apache.catalina.Service |
| Connector | 处理网络连接,将字节流转换为Request/Response对象。 |
org.apache.catalina.connector.Connector |
| Container | 处理Servlet请求的容器体系,采用责任链模式。 | org.apache.catalina.Container |
| Engine | 顶级容器,代表整个Servlet引擎,可包含多个Host。 | org.apache.catalina.Engine |
| Host | 虚拟主机,代表一个网络域名,可包含多个Context。 | org.apache.catalina.Host |
| Context | Web应用上下文,对应一个/WEB-INF/web.xml,可包含多个Wrapper。 |
org.apache.catalina.Context |
| Wrapper | 最底层容器,封装单个Servlet定义,管理其生命周期。 | org.apache.catalina.Wrapper |
| Pipeline & Valve | 容器内部处理请求的责任链管道与阀门机制。 | org.apache.catalina.Pipeline, org.apache.catalina.Valve |
| Mapper | 将请求URL映射到对应的Host、Context、Wrapper。 | org.apache.catalina.mapper.Mapper |
二、启动流程源码解析
启动入口为Bootstrap.main(),核心流程如下:
- 初始化类加载器 :创建
CatalinaClassLoader,用于加载Tomcat内部类,与Web应用类加载器隔离。 - 创建并启动
Catalina:Bootstrap通过反射调用Catalina的load()和start()方法。 - 解析
server.xml:Catalina.load()方法使用Digester解析配置文件,构建Server、Service、Connector、Engine等组件对象树。 - 初始化并启动组件 :调用
Server.init()和Server.start(),触发各组件生命周期。
关键代码片段(启动Server):
java
// org.apache.catalina.startup.Catalina
public void start() {
// ... 其他逻辑 getServer().init();
getServer().start();
// ... 后续处理(如等待关闭命令)
}
Server.init()会逐级向下初始化Service、Connector、Engine等所有子组件。
- Connector启动 :这是网络服务的关键。以HTTP Connector为例,其
start()方法会:- 启动关联的协议处理器 (如
Http11NioProtocol)。 - 协议处理器启动端点 (
Endpoint),如NioEndpoint,它会:- 创建服务器套接字(ServerSocket)并绑定端口。
- 启动Acceptor线程(接收新连接)。
- 启动Poller线程(处理已接收连接上的I/O事件)。
- 初始化工作线程池 (
Executor),用于执行具体的请求处理任务。
- 启动关联的协议处理器 (如
三、请求处理流程源码解析
当一个HTTP请求到达时,处理流程如下:
- Acceptor接收连接 :
Acceptor.run()方法循环调用serverSocket.accept(),接收新Socket连接,并将其注册到Poller。 - Poller处理I/O事件:Poller线程通过Selector监听Socket的读写事件。当通道可读时,Poller从线程池获取一个工作线程来处理该Socket。
- 协议处理器解析 :工作线程调用
Http11Processor等组件,按照HTTP协议解析Socket输入流,生成Tomcat内部的Request和Response对象。 - Adapter适配 :
CoyoteAdapter将协议层Request/Response对象适配为Servlet API标准的HttpServletRequest和HttpServletResponse对象。 - Mapper映射 :调用
Mapper.map()方法,根据请求的URL、主机名等信息,查找并确定处理该请求的Host、Context、Wrapper(Servlet)。 - 容器责任链调用 :请求被传递到
Engine的Pipeline,开始执行Valve链。核心调用顺序为:EngineValve->HostValve->ContextValve->WrapperValve。ContextValve会检查并触发该Web应用类加载器的资源加载。WrapperValve负责调用Wrapper.allocate()分配或创建Servlet实例,并最终调用FilterChain.doFilter()和Servlet.service()方法。
关键代码片段(WrapperValve调用Servlet):
java
// org.apache.catalina.core.StandardWrapperValve
public void invoke(Request request, Response response) {
// ... 前置逻辑(如加载Servlet类、实例化)
// 分配Servlet实例 Servlet servlet = wrapper.allocate();
// 创建ApplicationFilterChain并调用 ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
//依次调用Filter和Servlet的service方法 filterChain.doFilter(request.getRequest(), response.getResponse());
// ... 后置逻辑(如回收Servlet实例)
}
- 响应返回:Servlet处理完成后,响应沿原路返回,通过协议处理器写入Socket输出流,最终由工作线程完成连接清理。
四、核心设计思想与机制
- 生命周期统一管理 :所有核心组件均实现
Lifecycle接口,通过init()、start()、stop()、destroy()方法统一管理状态,采用观察者模式通知状态变化。 - 责任链模式 :
Pipeline和Valve机制是容器处理请求的核心,提供了高度的灵活性和可扩展性,允许开发者插入自定义处理逻辑。 - 分层类加载器 :Tomcat实现了自定义的类加载器体系(
WebappClassLoader),支持Web应用隔离、热部署,并遵循双亲委派模型的变体。 - 并发控制与线程池 :通过
LimitLatch控制连接数,使用Executor线程池处理请求,有效管理资源,防止过载。