tomcat生命周期管理

img

各种组件如何统一管理

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中,这个类就是统一的生命周期管理。

image-20220111200112034

public class StandardService extends LifecycleMBeanBase implements Service
    
public abstract class LifecycleMBeanBase extends LifecycleBase
        implements JmxEnabled

LifecycleBase

public 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()");
            }
            //  触发 INITIALIZING 事件的监听器
            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骨架抽象类,在抽象方法中就可以进行统一的处理。

从图上可以看到,LifeCycleBase 实现了 LifeCycle 接口中所有的方法,还定义了相应的抽象方法交给具体子类去实现,这是典型的模板设计模式

init()

这个方法逻辑比较清楚,主要完成了四步:

第一步,检查状态的合法性,比如当前状态必须是 NEW 然后才能进行初始化。

第二步,触发 INITIALIZING 事件的监听器:setStateInternal(LifecycleState.INITIALIZING, null, false);在这个 setStateInternal 方法里,会调用监听器的业务方法。

第三步,调用具体子类实现的抽象方法 initInternal() 方法。我在前面提到过,为了实现一键式启动,具体组件在实现 initInternal() 方法时,又会调用它的子组件的 init() 方法。

第四步,子组件初始化后,触发 INITIALIZED 事件的监听器,相应监听器的业务方法就会被调用。setStateInternal(LifecycleState.INITIALIZED, null, false);

总之,LifeCycleBase 调用了抽象方法来实现骨架逻辑。总之,LifeCycleBase 调用了抽象方法来实现骨架逻辑。

分为两种情况:

  • tomcat 自定义了一些监听器,这些监听器是父组件在创建子组件的过程中注册到子组件的。比如 MemoryLeakTrackingListener 监听器,用来检测 Context 容器中的内存泄漏,这个监听器是 Host 容器在创建 Context 容器时注册到 Context 中的。
  • 我们还可以在 server.xml 中定义自己的监听器,tomcat 在启动时会解析 server.xml,创建监听器并注册到容器组件。

LifeCycle源码分析

作用

组件生命周期方法的通用接口。 Catalina组件可以实现此接口(以及它们支持的功能的适当接口),以便提供一致的机制来启动和停止组件

状态图

tomcat中的事件触发是通过这些状态来判定的。

image-20220111215508887

  1. 所有状态都能转变为FAILED。
  2. ⼀个组件在STARTING_PREP、STARTING、STARTED状态调⽤start()⽅法不会产⽣影响。
  3. ⼀个组件在NEW状态调⽤start()⽅法时,会先调⽤init()⽅法。
  4. ⼀个组件在STOPPING_PREP、STOPPING、STOPPED状态调⽤stop⽅法不会产⽣影响。
  5. ⼀个组件在NEW状态调⽤stop()⽅法是,会将状态直接改为STOPPED。当组件自己启动失败去停止时,需要将子组件也进行停止,尽管某些⼦组件还没有启动。
  6. 其他状态相互转换都会抛异常。
  7. 合法的状态转换发⽣时都会触发相应的LifecycleEvent事件,⾮合法的转换不会触发事件。

接口定义

Lifecycle接口统一管理tomcat生命周期。一共做了4件事:

  • 定义13个string类型常量,用于LifecycleEvent时间的type属性中,用于区分组件发出的LifecycleEvent事件时的状态。
  • 定义三个管理监听器的方法,addLifecycleListener、findLifecycleListeners、removeLifecycleListener。
  • 定义4个生命周期的方法,init、start、stop、destory,用于执行生命周期的各个阶段的操作。
  • 定义了获取当前状态的两个方法,getState、getStateName、用于获取当前的状态。
public 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();
}

默认实现类

public abstract class LifecycleBase implements Lifecycle {
    // 源组件的当前状态,不同状态触发不同事件
    private volatile LifecycleState state = LifecycleState.NEW;
}

组件的 init() 和 start() 调用是由它的父组件的状态变化触发的,上层组件的初始化会触发子组件的初始化,上层组件的启动会触发子组件的启动,因此我们把组件的生命周期定义成一个个状态,把状态的转变看作是一个事件。而事件是有监听器的,在监听器里可以实现一些逻辑,并且监听器也可以方便的添加和删除,这就是典型的观察者模式

监听器相关方法

事件监听器需要三个参与者:

  • 事件对象:用于封装事件的信息,在事件监听器接口的同一方法中作为参数使用,继承自java.util.EventObject类。
  • 事件源:触发事件的源头,不同事件源触发不同事件类型。
  • 事件监听器:负责监听事件源发出的事件。实现 java.util.EventListener 接口。
// 用于事件通知的已注册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方法
@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方法
@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方法
@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方法
@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();
    }
}
设置状态方法
private 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接口。
public final class LifecycleEvent extends java.util.EventObject {
    public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
        super(lifecycle);
        this.type = type;
        this.data = data;
    }
}
public interface LifecycleListener {
    public void lifecycleEvent(LifecycleEvent event);
}
public 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();
        }
    }
}
// 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);
    }
}

模板方法

四个模板方法,由子类具体实现

protected abstract void initInternal() throws LifecycleException;
protected abstract void startInternal() throws LifecycleException;
protected abstract void stopInternal() throws LifecycleException;
protected abstract void destroyInternal() throws LifecycleException;

生命周期总体类图

image-20220112133828683

总结

通过提供init、start、stop、destory方法,通过相应的模板方法【模板设计模式】,提供组件的统一生命周期的管理、事件调度。