Tomcat生命周期管理

各种组件如何统一管理
Tomcat的架构设计是清晰的、模块化、它拥有很多组件,加入在启动Tomcat时一个一个组件启动,很容易遗漏组件,同时还会对后面的动态组件拓展带来麻烦。如果采用我们传统的方式的话,组件在启动过程中如果发生异常,会很难管理,比如你的下一个组件调用了start方法,但是如果它的上级组件还没有start甚至还没有init的话,Tomcat的启动会非常难管理,因此,Tomcat的设计者提出一个解决方案:用Lifecycle管理启动,停止、关闭。
生命周期统一接口
Tomcat内部架构中各个核心组件有包含与被包含关系,例如:Server包含了Service.Service又包含了Container和Connector,这个结构有一点像数据结构中的树,树的根结点没有父节点,其他节点有且仅有一个父节点,每一个父节点有0至多个子节点。所以,我们可以通过父容器启动它的子容器,这样只要启动根容器,就可以把其他所有的容器都启动,从而达到了统一的启动,停止、关闭的效果。
所有所有组件有一个统一的接口——Lifecycle,把所有的启动、停止、关闭、生命周期相关的方法都组织到一起,就可以很方便管理Tomcat各个容器组件的生命周期。
Lifecycle其实就是定义了一些状态常量和几个方法,主要方法是init,start,stop三个方法。
例如:Tomcat的Server组件的init负责遍历调用其包含所有的Service组件的init方法。
注意:Server只是一个接口,实现类为StandardServer,有意思的是,StandardServer没有init方法,init方法是在哪里,其实是在它的父类LifecycleBase中,这个类就是统一的生命周期管理。- COPYpublic class StandardService extends LifecycleMBeanBase implements Service
-
- public abstract class LifecycleMBeanBase extends LifecycleBase
- implements JmxEnabled
复制代码 LifecycleBase
- COPYpublic abstract class LifecycleBase implements Lifecycle {
- @Override
- public final synchronized void init() throws LifecycleException {
- //这个就是为了防止 组件启动的顺序不对
- if (!state.equals(LifecycleState.NEW)) {
- invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
- }
- try {
- //只打印核心组件
- if(this.getClass().getName().startsWith("org.apache.catalina.core")||this.getClass().getName().startsWith("org.apache.catalina.connector")){
- System.out.println(this.getClass()+"--init()");
- }
- setStateInternal(LifecycleState.INITIALIZING, null, false);
- //调用子类的initInternal方法
- initInternal();
- setStateInternal(LifecycleState.INITIALIZED, null, false);
- } catch (Throwable t) {
- handleSubClassException(t, "lifecycleBase.initFail", toString());
- }
- }
-
- }
复制代码 所以StandardServer最终只会调用到initInternal方法,这个方法会初始化子容器Service的init方法
为什么LifecycleBase这么玩,其实很多架构源码都是这么玩的,包括JDK的容器源码都是这么玩的,一个类,有一个接口,同时抽象一个抽象骨架类,把通用的实现放在抽象骨架类中,这样设计就方便组件的管理,使用LifecycleBase骨架抽象类,在抽象方法中就可以进行统一的处理。
LifeCycle源码分析
作用
组件生命周期方法的通用接口。 Catalina组件可以实现此接口(以及它们支持的功能的适当接口),以便提供一致的机制来启动和停止组件
状态图
Tomcat中的事件触发是通过这些状态来判定的。
- COPY* start()
- * -----------------------------
- * | |
- * | init() |
- * NEW -»-- INITIALIZING |
- * | | | | ------------------«-----------------------
- * | | |auto | | |
- * | | \|/ start() \|/ \|/ auto auto stop() |
- * | | INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»--- |
- * | | | | |
- * | |destroy()| | |
- * | --»-----«-- ------------------------«-------------------------------- ^
- * | | | |
- * | | \|/ auto auto start() |
- * | | STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»-----
- * | \|/ ^ | ^
- * | | stop() | | |
- * | | -------------------------- | |
- * | | | | |
- * | | | destroy() destroy() | |
- * | | FAILED ----»------ DESTROYING ---«----------------- |
- * | | ^ | |
- * | | destroy() | |auto |
- * | --------»----------------- \|/ |
- * | DESTROYED |
- * | |
- * | stop() |
- * ----»-----------------------------»------------------------------
复制代码 接口定义
Lifecycle接口统一管理Tomcat生命周期。一共做了4件事:
- 定义13个string类型常量,用于LifecycleEvent时间的type属性中,用于区分组件发出的LifecycleEvent事件时的状态。
- 定义三个管理监听器的方法,addLifecycleListener、findLifecycleListeners、removeLifecycleListener。
- 定义4个生命周期的方法,init、start、stop、destory,用于执行生命周期的各个阶段的操作。
- 定义了获取当前状态的两个方法,getState、getStateName、用于获取当前的状态。
- COPYpublic interface Lifecycle {
- // 13个状态常量值
- public static final String BEFORE_INIT_EVENT = "before_init";
- public static final String AFTER_INIT_EVENT = "after_init";
- public static final String START_EVENT = "start";
- public static final String BEFORE_START_EVENT = "before_start";
- public static final String AFTER_START_EVENT = "after_start";
- public static final String STOP_EVENT = "stop";
- public static final String BEFORE_STOP_EVENT = "before_stop";
- public static final String AFTER_STOP_EVENT = "after_stop";
- public static final String AFTER_DESTROY_EVENT = "after_destroy";
- public static final String BEFORE_DESTROY_EVENT = "before_destroy";
- public static final String PERIODIC_EVENT = "periodic";
- public static final String CONFIGURE_START_EVENT = "configure_start";
- public static final String CONFIGURE_STOP_EVENT = "configure_stop";
- // 3个监听器方法
- public void addLifecycleListener(LifecycleListener listener);
- public LifecycleListener[] findLifecycleListeners();
- public void removeLifecycleListener(LifecycleListener listener);
- // 4个生命周期方法
- public void init() throws LifecycleException;
- public void start() throws LifecycleException;
- public void stop() throws LifecycleException;
- public void destroy() throws LifecycleException;
- // 2个当前状态方法
- public LifecycleState getState();
- public String getStateName();
- }
复制代码 默认实现类
- COPYpublic abstract class LifecycleBase implements Lifecycle {
- // 源组件的当前状态,不同状态触发不同事件
- private volatile LifecycleState state = LifecycleState.NEW;
- }
复制代码 监听器相关方法
事件监听器需要三个参与者:
- 事件对象:用于封装事件的信息,在事件监听器接口的同一方法中作为参数使用,继承自java.util.EventObject类。
- 事件源:触发事件的源头,不同事件源触发不同事件类型。
- 事件监听器:负责监听事件源发出的事件。实现 java.util.EventListener 接口。
- COPY// 用于事件通知的已注册LifecycleListener列表
- private final List<LifecycleListener> lifecycleListeners =
- new CopyOnWriteArrayList<>();
- @Override
- public void addLifecycleListener(LifecycleListener listener) {
- lifecycleListeners.add(listener);
- }
- @Override
- public LifecycleListener[] findLifecycleListeners() {
- return lifecycleListeners.toArray(new LifecycleListener[0]);
- }
- @Override
- public void removeLifecycleListener(LifecycleListener listener) {
- lifecycleListeners.remove(listener);
- }
- // 子类根据当前状态触发不同事件,实现不同操作
- protected void fireLifecycleEvent(String type, Object data) {
- LifecycleEvent event = new LifecycleEvent(this, type, data);
- for (LifecycleListener listener : lifecycleListeners) {
- listener.lifecycleEvent(event);
- }
- }
复制代码 生命周期方法
LifecycleBase 类是Lifecycle 接口的默认实现,所有实现了生命周期的组件都直接或者间接的继承自LifecycleBase。
init方法
- COPY@Override
- public final synchronized void init() throws LifecycleException {
- // 只有 NEW 状态可以调用
- if (!state.equals(LifecycleState.NEW)) {
- invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
- }
- // 设置 生命周期状态 -- INITIALIZING,触发相应事件
- setStateInternal(LifecycleState.INITIALIZING, null, false);
- // 模板方法,由具体子类实现
- initInternal();
- // 执行完成,设置生命周期状态 -- INITIALIZED,触发相应事件
- setStateInternal(LifecycleState.INITIALIZED, null, false);
- }
复制代码 Start方法
- COPY@Override
- public final synchronized void start() throws LifecycleException {
- // 此三种状态不执行
- if (LifecycleState.STARTING_PREP.equals(state) ||
- LifecycleState.STARTING.equals(state) ||
- LifecycleState.STARTED.equals(state)) {
- return;
- }
- // NEW 状态 执行 init 方法
- if (state.equals(LifecycleState.NEW)) {
- init();
- // 启动失败,调用 stop 方法
- } else if (state.equals(LifecycleState.FAILED)) {
- stop();
- // 其它状态,非法操作
- } else if (!state.equals(LifecycleState.INITIALIZED) &&
- !state.equals(LifecycleState.STOPPED)) {
- throw new LifecycleException()
- }
- // 设置启动状态为 STARTING_PREP【开始准备】
- setStateInternal(LifecycleState.STARTING_PREP, null, false);
- startInternal();
- // 调用完成后判断组件启动状态
- if (state.equals(LifecycleState.FAILED)) {
- stop();
- } else if (!state.equals(LifecycleState.STARTING)) {
- throw new LifecycleException();
- } else {
- setStateInternal(LifecycleState.STARTED, null, false);
- }
- }
复制代码 stop方法
- COPY@Override
- public final synchronized void stop() throws LifecycleException {
- // STOPPING_PREP、STOPPING、STOPPED此三种状态不予执行
- if (LifecycleState.STOPPING_PREP.equals(state) ||
- LifecycleState.STOPPING.equals(state) ||
- LifecycleState.STOPPED.equals(state)) {
- return;
- }
- // 如果状态为 NEW、修改为 STOPPED
- if (state.equals(LifecycleState.NEW)) {
- state = LifecycleState.STOPPED;
- return;
- }
- // 不为 STARTED、FAILED 2种状态,抛出异常
- if (!state.equals(LifecycleState.STARTED) &&
- !state.equals(LifecycleState.FAILED)) {
- throw new LifecycleException();
- }
- try {
- // 启动失败,触发事件,否则设置生命周期状态
- if (state.equals(LifecycleState.FAILED)) {
- fireLifecycleEvent(BEFORE_STOP_EVENT, null);
- } else {
- setStateInternal(LifecycleState.STOPPING_PREP, null, false);
- }
- // 调用模板方法
- stopInternal();
- if (!state.equals(LifecycleState.STOPPING) &&
- !state.equals(LifecycleState.FAILED)) {
- throw new LifecycleException();
- }
- setStateInternal(LifecycleState.STOPPED, null, false);
- } catch (Throwable t) {
- setStateInternal(LifecycleState.FAILED, null, false);
- throw new LifecycleException();
- } finally {
- if (this instanceof Lifecycle.SingleUse) {
- setStateInternal(LifecycleState.STOPPED, null, false);
- destroy();
- }
- }
- }
复制代码 destroy方法
- COPY@Override
- public final synchronized void destroy() throws LifecycleException {
- // 启动失败,先调用 stop 方法
- if (LifecycleState.FAILED.equals(state)) {
- stop();
- }
- // DESTROYING、DESTROYED不执行了
- if (LifecycleState.DESTROYING.equals(state) ||
- LifecycleState.DESTROYED.equals(state)) {
- return;
- }
- // 非法状态
- if (!state.equals(LifecycleState.STOPPED) &&
- !state.equals(LifecycleState.FAILED) &&
- !state.equals(LifecycleState.NEW) &&
- !state.equals(LifecycleState.INITIALIZED)) {
- throw new LifecycleException();
- }
- try {
- setStateInternal(LifecycleState.DESTROYING, null, false);
- destroyInternal();
- setStateInternal(LifecycleState.DESTROYED, null, false);
- } catch (Throwable t) {
- setStateInternal(LifecycleState.FAILED, null, false);
- throw new LifecycleException();
- }
- }
复制代码 设置状态方法
- COPYprivate synchronized void setStateInternal(LifecycleState state,
- Object data, boolean check) throws LifecycleException {
- // 检查参数
- if (check) {
- if (state == null) {
- throw new LifecycleException();
- return;
- }
- if (!(state == LifecycleState.FAILED ||
- (this.state == LifecycleState.STARTING_PREP &&
- state == LifecycleState.STARTING) ||
- (this.state == LifecycleState.STOPPING_PREP &&
- state == LifecycleState.STOPPING) ||
- (this.state == LifecycleState.FAILED &&
- state == LifecycleState.STOPPING))) {
- throw new LifecycleException();
- }
- }
- this.state = state;
- String lifecycleEvent = state.getLifecycleEvent();
- if (lifecycleEvent != null) {
- fireLifecycleEvent(lifecycleEvent, data);
- }
- }
复制代码 监听机制
事件监听器需要三个参与者:
- 事件对象—用于封装事件的信息,在事件监听器接口的统一方法中作为参数,一般继承 java.util.EventObjecct类。
- 事件源—触发事件对的源头,不同事件源触发不同事件。
- 事件监听器—负责监听事件源发出的事件,发生事件时,事件源调用事件监听器的统一方法处理。监听器一般实现java.util.EventListener接口。
- COPYpublic final class LifecycleEvent extends java.util.EventObject {
- public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
- super(lifecycle);
- this.type = type;
- this.data = data;
- }
- }
- COPYpublic interface LifecycleListener {
- public void lifecycleEvent(LifecycleEvent event);
- }
- COPYpublic class HostConfig implements LifecycleListener {
- @Override
- public void lifecycleEvent(LifecycleEvent event) {
- try {
- host = (Host) event.getLifecycle();
- if (host instanceof StandardHost) {
- setCopyXML(((StandardHost) host).isCopyXML());
- setDeployXML(((StandardHost) host).isDeployXML());
- setUnpackWARs(((StandardHost) host).isUnpackWARs());
- setContextClass(((StandardHost) host).getContextClass());
- }
- } catch (ClassCastException e) {
- return;
- }
- // Process the event that has occurred
- if (event.getType().equals(Lifecycle.PERIODIC_EVENT)) {
- check();
- } else if (event.getType().equals(Lifecycle.BEFORE_START_EVENT)) {
- beforeStart();
- } else if (event.getType().equals(Lifecycle.START_EVENT)) {
- start();
- } else if (event.getType().equals(Lifecycle.STOP_EVENT)) {
- stop();
- }
- }
- }
- COPY// LifecycleBase.startInternal
- this.state = state;
- String lifecycleEvent = state.getLifecycleEvent();
- if (lifecycleEvent != null) {
- fireLifecycleEvent(lifecycleEvent, data);
- }
- protected void fireLifecycleEvent(String type, Object data) {
- LifecycleEvent event = new LifecycleEvent(this, type, data);
- for (LifecycleListener listener : lifecycleListeners) {
- listener.lifecycleEvent(event);
- }
- }
复制代码 模板方法
四个模板方法,由子类具体实现
- COPYprotected abstract void initInternal() throws LifecycleException;
- protected abstract void startInternal() throws LifecycleException;
- protected abstract void stopInternal() throws LifecycleException;
- protected abstract void destroyInternal() throws LifecycleException;
复制代码 总结
通过提供init、start、stop、destory方法,通过相应的模板方法【模板设计模式】,提供组件的统一生命周期的管理、事件调度。
本文由传智教育博学谷狂野架构师教研团队发布。
如果本文对您有帮助,欢迎关注和点赞;如果您有任何建议也可留言评论或私信,您的支持是我坚持创作的动力。
转载请注明出处!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |