Tomcat核心源码解析:分层架构与请求处理

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(),核心流程如下:

  1. 初始化类加载器 :创建CatalinaClassLoader,用于加载Tomcat内部类,与Web应用类加载器隔离。
  2. 创建并启动CatalinaBootstrap通过反射调用Catalinaload()start()方法。
  3. 解析server.xmlCatalina.load()方法使用Digester解析配置文件,构建ServerServiceConnectorEngine等组件对象树。
  4. 初始化并启动组件 :调用Server.init()Server.start(),触发各组件生命周期。

关键代码片段(启动Server)

java 复制代码
// org.apache.catalina.startup.Catalina
public void start() {
    // ... 其他逻辑 getServer().init();
    getServer().start();
    // ... 后续处理(如等待关闭命令)
}

Server.init()会逐级向下初始化ServiceConnectorEngine等所有子组件。

  1. Connector启动 :这是网络服务的关键。以HTTP Connector为例,其start()方法会:
    • 启动关联的协议处理器 (如Http11NioProtocol)。
    • 协议处理器启动端点Endpoint),如NioEndpoint,它会:
      • 创建服务器套接字(ServerSocket)并绑定端口。
      • 启动Acceptor线程(接收新连接)。
      • 启动Poller线程(处理已接收连接上的I/O事件)。
      • 初始化工作线程池Executor),用于执行具体的请求处理任务。

三、请求处理流程源码解析

当一个HTTP请求到达时,处理流程如下:

  1. Acceptor接收连接Acceptor.run()方法循环调用serverSocket.accept(),接收新Socket连接,并将其注册到Poller。
  2. Poller处理I/O事件:Poller线程通过Selector监听Socket的读写事件。当通道可读时,Poller从线程池获取一个工作线程来处理该Socket。
  3. 协议处理器解析 :工作线程调用Http11Processor等组件,按照HTTP协议解析Socket输入流,生成Tomcat内部的RequestResponse对象。
  4. Adapter适配CoyoteAdapter将协议层Request/Response对象适配为Servlet API标准的HttpServletRequestHttpServletResponse对象。
  5. Mapper映射 :调用Mapper.map()方法,根据请求的URL、主机名等信息,查找并确定处理该请求的Host、Context、Wrapper(Servlet)。
  6. 容器责任链调用 :请求被传递到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实例)
}
  1. 响应返回:Servlet处理完成后,响应沿原路返回,通过协议处理器写入Socket输出流,最终由工作线程完成连接清理。

四、核心设计思想与机制

  1. 生命周期统一管理 :所有核心组件均实现Lifecycle接口,通过init()start()stop()destroy()方法统一管理状态,采用观察者模式通知状态变化。
  2. 责任链模式PipelineValve机制是容器处理请求的核心,提供了高度的灵活性和可扩展性,允许开发者插入自定义处理逻辑。
  3. 分层类加载器 :Tomcat实现了自定义的类加载器体系(WebappClassLoader),支持Web应用隔离、热部署,并遵循双亲委派模型的变体。
  4. 并发控制与线程池 :通过LimitLatch控制连接数,使用Executor线程池处理请求,有效管理资源,防止过载。

参考来源