第二章-Tomcat核心架构拆解
💡 第二章:Tomcat 核心架构拆解
目录
- 2.1 整体分层结构
- 2.2 各组件职责详解
- 2.3 server.xml 配置示例
- 2.4 生命周期接口与启动流程
- 2.5 组件间通信机制
- 2.6 本章小结
2.1 整体分层结构
架构层次图
层次关系说明
| 层次 | 组件 | 数量关系 | 职责 |
|---|---|---|---|
| Server | 1个 | 1:1 | 整个 Tomcat 实例的容器 |
| Service | 1个 | 1:1 | 服务单元,包含 Connector 和 Engine |
| Connector | 多个 | 1:N | 协议适配,处理不同协议请求 |
| Engine | 1个 | 1:1 | 请求处理引擎,路由请求到 Host |
| Host | 多个 | 1:N | 虚拟主机,根据域名路由 |
| Context | 多个 | 1:N | Web 应用上下文,对应一个应用 |
| Wrapper | 多个 | 1:N | Servlet 包装器,管理 Servlet 实例 |
2.2 各组件职责详解
2.2.1 Server 组件
职责
- 整体容器:Tomcat 实例的根容器
- 生命周期管理:启动、停止整个 Tomcat 实例
- 配置管理:加载和管理全局配置
核心功能
// Server 接口核心方法
public interface Server extends Lifecycle {// 添加服务void addService(Service service);// 移除服务void removeService(Service service);// 查找服务Service findService(String name);// 获取所有服务Service[] findServices();
}
配置示例
<Server port="8005" shutdown="SHUTDOWN"><!-- 全局监听器 --><Listener className="org.apache.catalina.startup.VersionLoggerListener" /><Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /><Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /><Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /><Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /><!-- 全局资源 --><GlobalNamingResources><Resource name="UserDatabase" auth="Container"type="org.apache.catalina.UserDatabase"description="User database that can be updated and saved"factory="org.apache.catalina.users.MemoryUserDatabaseFactory"pathname="conf/tomcat-users.xml" /></GlobalNamingResources><!-- 服务配置 --><Service name="Catalina"><!-- Connector 和 Engine 配置 --></Service>
</Server>
2.2.2 Service 组件
职责
- 服务单元:将 Connector 和 Engine 组合在一起
- 请求路由:将 Connector 接收的请求路由到 Engine
- 生命周期协调:协调 Connector 和 Engine 的生命周期
核心功能
// Service 接口核心方法
public interface Service extends Lifecycle {// 获取引擎Engine getContainer();// 设置引擎void setContainer(Engine engine);// 添加连接器void addConnector(Connector connector);// 移除连接器void removeConnector(Connector connector);// 查找连接器Connector[] findConnectors();
}
2.2.3 Connector 组件
职责
- 协议适配:将不同协议的请求转换为标准格式
- I/O 处理:处理网络 I/O 操作
- 请求解析:解析 HTTP 请求头和参数
支持的协议
| 协议 | 实现类 | 说明 |
|---|---|---|
| HTTP/1.1 | Http11NioProtocol | 非阻塞 I/O |
| HTTP/1.1 | Http11AprProtocol | APR 原生实现 |
| HTTP/2 | Http2Protocol | HTTP/2 协议支持 |
| AJP | AjpNioProtocol | Apache JServ Protocol |
配置示例
<!-- HTTP Connector -->
<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100"compression="on"compressionMinSize="2048"compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json" /><!-- AJP Connector -->
<Connector port="8009" protocol="AJP/1.3"redirectPort="8443"maxThreads="200"minSpareThreads="10"maxSpareThreads="50" />
2.2.4 Engine 组件
职责
- 请求处理引擎:处理所有请求的入口点
- Host 路由:根据请求的 Host 头路由到相应的 Host
- 默认 Host:处理没有匹配 Host 的请求
核心功能
// Engine 接口核心方法
public interface Engine extends Container {// 获取默认主机String getDefaultHost();// 设置默认主机void setDefaultHost(String defaultHost);// 获取主机Host getHost(String name);// 添加主机void addChild(Container child);
}
配置示例
<Engine name="Catalina" defaultHost="localhost"><!-- 集群配置 --><Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/><!-- 主机配置 --><Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"><!-- Context 配置 --></Host><!-- 虚拟主机配置 --><Host name="api.example.com" appBase="webapps/api"unpackWARs="true" autoDeploy="true"><Context path="" docBase="api-app" /></Host>
</Engine>
2.2.5 Host 组件
职责
- 虚拟主机:根据域名提供不同的 Web 服务
- Context 路由:根据请求路径路由到相应的 Context
- 应用管理:管理部署在主机上的 Web 应用
核心功能
// Host 接口核心方法
public interface Host extends Container {// 获取应用基础目录String getAppBase();// 设置应用基础目录void setAppBase(String appBase);// 查找上下文Context findContext(String name);// 添加上下文void addChild(Container child);
}
配置示例
<Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"xmlValidation="false" xmlNamespaceAware="false"><!-- 应用上下文 --><Context path="/myapp" docBase="myapp" reloadable="true"><!-- 应用特定配置 --></Context><!-- 默认应用 --><Context path="" docBase="ROOT" /><!-- 访问日志 --><Valve className="org.apache.catalina.valves.AccessLogValve"directory="logs"prefix="localhost_access_log"suffix=".txt"pattern="%h %l %u %t "%r" %s %b" />
</Host>
2.2.6 Context 组件
职责
- Web 应用上下文:代表一个 Web 应用
- Servlet 路由:根据 URL 路径路由到相应的 Servlet
- 资源管理:管理应用内的静态资源和类文件
核心功能
// Context 接口核心方法
public interface Context extends Container {// 获取应用路径String getPath();// 设置应用路径void setPath(String path);// 获取文档基础目录String getDocBase();// 设置文档基础目录void setDocBase(String docBase);// 添加 Servlet 映射void addServletMappingDecoded(String pattern, String name);
}
配置示例
<Context path="/myapp" docBase="myapp" reloadable="true"><!-- 环境变量 --><Environment name="app.config" value="production" type="java.lang.String" /><!-- 资源引用 --><Resource name="jdbc/MyDB" auth="Container"type="javax.sql.DataSource"driverClassName="com.mysql.jdbc.Driver"url="jdbc:mysql://localhost:3306/mydb"username="user"password="pass"maxTotal="20"maxIdle="10"maxWaitMillis="10000" /><!-- Servlet 映射 --><Servlet name="MyServlet" class="com.example.MyServlet" /><ServletMapping name="MyServlet" urlPattern="/myservlet" />
</Context>
2.2.7 Wrapper 组件
职责
- Servlet 包装器:管理单个 Servlet 实例
- 生命周期管理:管理 Servlet 的 init、service、destroy 方法
- 实例管理:管理 Servlet 实例的创建和销毁
核心功能
// Wrapper 接口核心方法
public interface Wrapper extends Container {// 获取 Servlet 类名String getServletClass();// 设置 Servlet 类名void setServletClass(String servletClass);// 加载 ServletServlet load() throws ServletException;// 分配 Servlet 实例Servlet allocate() throws ServletException;
}
2.3 server.xml 配置示例
完整配置示例
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN"><!-- 全局监听器 --><Listener className="org.apache.catalina.startup.VersionLoggerListener" /><Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /><Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /><Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /><Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /><!-- 全局资源 --><GlobalNamingResources><Resource name="UserDatabase" auth="Container"type="org.apache.catalina.UserDatabase"description="User database that can be updated and saved"factory="org.apache.catalina.users.MemoryUserDatabaseFactory"pathname="conf/tomcat-users.xml" /></GlobalNamingResources><!-- 服务配置 --><Service name="Catalina"><!-- HTTP 连接器 --><Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"maxThreads="200"minSpareThreads="10"maxSpareThreads="50"acceptCount="100"compression="on"compressionMinSize="2048"compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json"useSendfile="true" /><!-- AJP 连接器 --><Connector port="8009" protocol="AJP/1.3"redirectPort="8443"maxThreads="200"minSpareThreads="10"maxSpareThreads="50" /><!-- 引擎配置 --><Engine name="Catalina" defaultHost="localhost"><!-- 集群配置 --><Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/><!-- 主机配置 --><Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"xmlValidation="false" xmlNamespaceAware="false"><!-- 应用上下文 --><Context path="/myapp" docBase="myapp" reloadable="true"><Resource name="jdbc/MyDB" auth="Container"type="javax.sql.DataSource"driverClassName="com.mysql.jdbc.Driver"url="jdbc:mysql://localhost:3306/mydb"username="user"password="pass"maxTotal="20"maxIdle="10"maxWaitMillis="10000" /></Context><!-- 访问日志 --><Valve className="org.apache.catalina.valves.AccessLogValve"directory="logs"prefix="localhost_access_log"suffix=".txt"pattern="%h %l %u %t "%r" %s %b" /></Host><!-- 虚拟主机 --><Host name="api.example.com" appBase="webapps/api"unpackWARs="true" autoDeploy="true"><Context path="" docBase="api-app" /></Host></Engine></Service>
</Server>
配置层次关系
2.4 生命周期接口与启动流程
2.4.1 Lifecycle 接口
生命周期状态
public enum LifecycleState {NEW(false, null),INITIALIZING(false, "before_init"),INITIALIZED(false, "after_init"),STARTING_PREP(false, "before_start"),STARTING(true, "configure_start"),STARTED(true, "after_start"),STOPPING_PREP(true, "before_stop"),STOPPING(false, "configure_stop"),STOPPED(false, "after_stop"),FAILED(false, null),DESTROYING(false, "before_destroy"),DESTROYED(false, "after_destroy"),MUST_STOP(true, null),MUST_DESTROY(false, null);
}
核心方法
public interface Lifecycle {// 添加生命周期监听器void addLifecycleListener(LifecycleListener listener);// 移除生命周期监听器void removeLifecycleListener(LifecycleListener listener);// 获取生命周期监听器LifecycleListener[] findLifecycleListeners();// 启动void start() throws LifecycleException;// 停止void stop() throws LifecycleException;// 获取状态LifecycleState getState();// 获取状态名称String getStateName();
}
2.4.2 启动流程
启动序列图
详细启动步骤
1. Bootstrap 启动
// Bootstrap.main() 方法
public static void main(String args[]) {Bootstrap bootstrap = new Bootstrap();bootstrap.init();bootstrap.start();
}
2. Catalina 初始化
// Catalina.start() 方法
public void start() {// 1. 创建服务器if (getServer() == null) {load();}// 2. 启动服务器if (getServer() == null) {log.fatal("Cannot start server. Server object is not configured.");return;}long t1 = System.nanoTime();// 3. 启动服务器getServer().start();long t2 = System.nanoTime();if(log.isInfoEnabled()) {log.info("Server startup in " + ((t2 - t1) / 1000000) + " ms");}
}
3. 组件初始化顺序
// 初始化顺序
1. Server.init()
2. Service.init()
3. Connector.init()
4. Engine.init()
5. Host.init()
6. Context.init()
7. Wrapper.init()
4. 组件启动顺序
// 启动顺序
1. Server.start()
2. Service.start()
3. Engine.start()
4. Host.start()
5. Context.start()
6. Wrapper.start()
7. Connector.start()
2.5 组件间通信机制
2.5.1 请求流转机制
请求处理流程图
关键适配器
// CoyoteAdapter 适配器
public class CoyoteAdapter implements Adapter {@Overridepublic void service(org.apache.coyote.Request req, org.apache.coyote.Response res) throws Exception {// 1. 创建 Request 和 Response 对象Request request = (Request) req.getNote(ADAPTER_NOTES);Response response = (Response) res.getNote(ADAPTER_NOTES);// 2. 设置请求属性request.setCoyoteRequest(req);response.setCoyoteResponse(res);// 3. 调用容器的 service 方法connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);}
}
2.5.2 Pipeline 和 Valve 机制
Pipeline 接口
public interface Pipeline {// 获取基础 ValveValve getBasic();// 设置基础 Valvevoid setBasic(Valve valve);// 添加 Valvevoid addValve(Valve valve);// 移除 Valvevoid removeValve(Valve valve);// 获取第一个 ValveValve getFirst();
}
Valve 接口
public interface Valve {// 获取下一个 ValveValve getNext();// 设置下一个 Valvevoid setNext(Valve valve);// 处理请求void invoke(Request request, Response response) throws IOException, ServletException;// 获取信息String getInfo();
}
Valve 链示例
// 标准 Valve 链
StandardEngine -> StandardHost -> StandardContext -> StandardWrapper// 每个容器都有对应的 Pipeline
Engine: EngineValve
Host: AccessLogValve -> ErrorReportValve -> StandardHostValve
Context: StandardContextValve
Wrapper: StandardWrapperValve
2.6 本章小结
关键要点
-
分层架构:
- Server → Service → Connector + Engine → Host → Context → Wrapper
- 每层都有明确的职责和接口定义
-
组件职责:
- Server:整体容器,管理全局配置
- Service:服务单元,协调 Connector 和 Engine
- Connector:协议适配,处理网络 I/O
- Engine:请求引擎,路由到 Host
- Host:虚拟主机,管理 Web 应用
- Context:应用上下文,管理 Servlet
- Wrapper:Servlet 包装器,管理 Servlet 实例
-
生命周期管理:
- 所有组件都实现 Lifecycle 接口
- 启动顺序:Server → Service → Engine → Host → Context → Wrapper → Connector
- 停止顺序:与启动顺序相反
-
通信机制:
- Pipeline 和 Valve 机制实现请求处理链
- CoyoteAdapter 负责协议适配
- 每个容器都有对应的 Valve 链
配置要点
-
server.xml 配置:
- 严格按照层次结构配置
- 注意组件的依赖关系
- 合理设置连接器参数
-
性能考虑:
- 连接器线程池配置
- 主机和应用管理
- 访问日志和监控
下一步学习
在下一章中,我们将深入探讨 Tomcat 的请求处理原理,了解从 HTTP 请求到 Servlet 响应的完整流程,以及各个组件在请求处理中的作用。
相关资源:
- Tomcat 架构文档
- Servlet 规范文档
- Tomcat 配置参考
