Tomcat-整体架构和Lifecycle
基于Tomcat-8.5.x版本,简单分析了整体的架构和核心组件。并详细分析和总结了Lifecycle机制
核心组件和架构
Tomcat 的架构可以抽象为一棵树,核心组件结构如下:
- 根节点是 Server,表示整个 Tomcat 实例(即一个 JVM 进程)
- Server 下包含一个或多个 Service,代表一组 Web 服务
- 每个
Service
包含:- 一个或多个 Connector,负责监听不同协议/端口的请求(如 HTTP、HTTPS)
- 唯一的一个 Engine,与Service一对一的关系,用于处理由 Connector 接收到的请求
- Engine 下包含多个 Host,每个
Host
对应一个虚拟主机(通过域名区分) - 每个 Host管理多个 Context,每个
Context
对应一个 Web 应用(即一个 war) - 每个 Context 下包含多个 Wrapper,每个
Wrapper
对应一个具体的 Servlet
Lifecycle
Lifecycle
是 Tomcat 中最核心的接口之一。所有关键组件都实现了该接口,以便在生命周期事件(如init、start、stop等)到来时执行自身的职责,并将事件级联传递给子组件。因此,深入理解 Lifecycle
的作用和机制,是阅读和掌握 Tomcat 源码的基础。
public interface Lifecycle {
// ======================== 生命周期事件常量 ========================
String BEFORE_INIT_EVENT = "before_init";
String AFTER_INIT_EVENT = "after_init";
String BEFORE_START_EVENT = "before_start";
String START_EVENT = "start";
String AFTER_START_EVENT = "after_start";
String BEFORE_STOP_EVENT = "before_stop";
String STOP_EVENT = "stop";
String AFTER_STOP_EVENT = "after_stop";
String BEFORE_DESTROY_EVENT = "before_destroy";
String AFTER_DESTROY_EVENT = "after_destroy";
/** 周期性事件(如后台定时任务触发) */
String PERIODIC_EVENT = "periodic";
/** 配置启动事件(内部扩展使用) */
String CONFIGURE_START_EVENT = "configure_start";
/** 配置停止事件(内部扩展使用) */
String CONFIGURE_STOP_EVENT = "configure_stop";
// ======================== 生命周期监听器相关方法 ========================
void addLifecycleListener(LifecycleListener listener);
LifecycleListener[] findLifecycleListeners();
void removeLifecycleListener(LifecycleListener listener);
// ======================== 生命周期控制方法 ========================
/**
* 初始化组件。组件只能初始化一次,且必须在启动前完成。
*/
void init() throws LifecycleException;
/**
* 启动组件。如果未初始化,会隐式调用 init()
*/
void start() throws LifecycleException;
/**
* 停止组件。可在调用 start() 后再次调用以恢复运行
*/
void stop() throws LifecycleException;
/**
* 销毁组件,释放资源。此操作不可逆。
*/
void destroy() throws LifecycleException;
LifecycleState getState();
String getStateName();
/**
* 标记接口:表示该组件只能使用一次(单次使用后即不可重启)
*/
interface SingleUse {
}
}
LifecycleState
组件的生命周期状态枚举。每个状态标记了当前组件是否处于“可用”状态(available),以及对应的生命周期事件名(lifecycleEvent)
public enum LifecycleState {
// 初始状态,尚未进行任何初始化操作
NEW(false, null),
// ================= 初始化阶段 =================
// 初始化中,调用 init() 时进入此状态,发布 before_init 事件
INITIALIZING(false, Lifecycle.BEFORE_INIT_EVENT),
// 初始化完成,进入 INITIALIZED 状态,发布 after_init 事件
INITIALIZED(false, Lifecycle.AFTER_INIT_EVENT),
// ================= 启动阶段 =================
// 启动准备中,准备启动前进入该状态,发布 before_start 事件
STARTING_PREP(false, Lifecycle.BEFORE_START_EVENT),
// 正在启动,执行 startInternal() 时进入此状态,发布 start 事件
STARTING(true, Lifecycle.START_EVENT),
// 启动完成,组件已处于工作状态,发布 after_start 事件
STARTED(true, Lifecycle.AFTER_START_EVENT),
// ================= 停止阶段 =================
// 停止准备阶段,准备停止时进入该状态,发布 before_stop 事件
STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT),
// 正在停止,组件关闭过程中进入该状态,发布 stop 事件
STOPPING(false, Lifecycle.STOP_EVENT),
// 停止完成,组件已不可用,发布 after_stop 事件
STOPPED(false, Lifecycle.AFTER_STOP_EVENT),
// ================= 销毁阶段 =================
// 销毁准备阶段,发布 before_destroy 事件
DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT),
// 销毁完成,组件进入不可恢复终态,发布 after_destroy 事件
DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT),
// ================= 异常状态 =================
// 异常失败状态,组件启动或运行中发生未处理异常,进入失败态。无生命周期事件发布
FAILED(false, null);
/**
* 当前状态是否为组件的“可用”状态,即是否可对外提供服务(如 STARTING、STARTED 等)
*/
private final boolean available;
private final String lifecycleEvent;
LifecycleState(boolean available, String lifecycleEvent) {
this.available = available;
this.lifecycleEvent = lifecycleEvent;
}
public boolean isAvailable() {
return available;
}
public String getLifecycleEvent() {
return lifecycleEvent;
}
}
LifecycleBase
LifecycleBase
是 Lifecycle
接口的基础实现类,提供了生命周期控制方法(如 init()
、start()
、stop()
、destroy()
)的通用模板逻辑。Tomcat 中绝大多数实现了 Lifecycle
接口的核心组件,都会继承该类,从而复用其统一的状态管理和事件分发机制。
核心start方法分析如下,(其余的init,stop等方法差不太多,就不做详细的分析了)
public abstract class LifecycleBase implements Lifecycle {
/**
* 启动组件。线程安全,具备幂等性。
*
* 生命周期状态迁移如下:
* NEW -> INITIALIZED -> STARTING_PREP -> STARTING -> STARTED
* 如果启动失败,将进入 FAILED 状态。
*/
public final synchronized void start() throws LifecycleException {
if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
LifecycleState.STARTED.equals(state)) {
// 正在启动中或已启动,无视直接返回
return;
}
// ============= 前置状态判断 =================
if (state.equals(LifecycleState.NEW)) {
// 如果还是初始化状态,就先初始化
init();
} else if (state.equals(LifecycleState.FAILED)) {
// 若之前启动失败,先尝试停止,清理资源后重新启动
stop();
} else if (!state.equals(LifecycleState.INITIALIZED) &&
!state.equals(LifecycleState.STOPPED)) {
// 其余非法前置状态,直接异常
invalidTransition(Lifecycle.BEFORE_START_EVENT);
}
// ============== 到这表示前置状态处理完毕,可以真正start了 ===================
try {
// 设置状态为 STARTING_PREP,并发布 before_start 事件
setStateInternal(LifecycleState.STARTING_PREP, null, false);
// 调用子类实现的实际启动逻辑(模板方法模式)
startInternal();
// ============ 走到这,正常情况state就应该为STARTING了 =================
if (state.equals(LifecycleState.FAILED)) {
// 启动失败,执行stop
stop();
} else if (!state.equals(LifecycleState.STARTING)) {
// 非STARTING(正常不应该出现,避免子类实现不规范的一种fallback),直接抛异常
invalidTransition(Lifecycle.AFTER_START_EVENT);
} else {
// 正常会走到这,状态自动置为STARTED。并发布 after_start 事件
setStateInternal(LifecycleState.STARTED, null, false);
}
} catch (Throwable t) {
handleSubClassException(t, "lifecycleBase.startFail", toString());
}
}
}
总结
Lifecycle状态转换图
状态机核心要点:
- 启动组件必定要先init,也只会调用一次init
- start和stop状态可以循环相互转化(即STOPPED状态不是终态)
- NEW可直接到STOPPED状态(很少这么用)
- DESTROYED才是终态,不可逆转(FAILED都不是终态,它还可以stop() -> startI(),虽然不一定成功)