Tomcat架构以及生命周期和事件监听

本文详细介绍了Tomcat的架构,包括Server、Service、Container、Connector等组件及其职责。同时,阐述了Tomcat的生命周期管理,展示了从NEW到DESTROYED各状态间的流转规则,并解释了Lifecycle接口及LifecycleState枚举的重要方法。此外,还讨论了事件监听机制,强调了事件监听器在组件状态变化时的角色。
摘要由CSDN通过智能技术生成

讲一下tomcat的架构和生命周期和事件监听机制,因为东西很多,后面的tomcat源码中会进行详细讲解;

Tomcat结构

下面是前辈们对tomcat架构诠释比较详细的了。我们来看下它的构成
在这里插入图片描述

  • Server: 表示服务器,它提供了一种优雅的方式来启动和停止整个系统,不必单独启停连接器和容器;它是Tomcat构成的顶级构成元素,所有一切均包含在Server中; Service: 表示服务,Server可以运行多个服务。比如一个Tomcat里面可运行订单服务、支付服务、用户服务等等;
  • Server: 其实现类StandardServer可以包含一个到多个Services, Service的实现类为StandardService调用了容器(Container)接口,其实是调用了Servlet Engine(引擎),而且StandardService类中也指明了该Service归属的Server;
  • Container: 表示容器,可以看做Servlet容器;引擎(Engine)、主机(Host)、上下文(Context)和Wraper均继承自Container接口,所以它们都是容器。
    • Engine – 引擎
    • Host – 主机
    • Context – 上下文
    • Wrapper – 包装器
  • Connector: 表示连接器, 它将Service和Container连接起来,首先它需要注册到一个Service,它的作用就是把来自客户端的请求转发到Container(容器),这就是它为什么称作连接器, 它支持的协议如下:
    • 支持AJP协议
    • 支持Http协议
    • 支持Https协议
  • Service内部还有各种支撑组件,下面简单罗列一下这些组件
    • Manager – 管理器,
    • 用于管理会话Session Logger – 日志器,
    • 用于管理日志
    • Loader – 加载器,和类加载有关,只会开放给Context所使用
    • Pipeline – 管道组件,配合Valve实现过滤器功能
    • Valve – 阀门组件,配合Pipeline实现过滤器功能
    • Realm – 认证授权组件在这里插入图片描述

Tomcat生命周期

tomcat架构是一种树状的层级管理结构,组件会有自己的父节点,也可以有自己的孩子节点,每个节点都是组件,每个组件都有生命周期,为了管理方便,子节点的生命周期交给父节点来管理,每个组件的都有自己生命周期的方法,但是启动的入口在父节点,父节点持有子节点的引用,所以可以一层一层的执行生命周期的引用。

每个组件的生命周期的管理主要是由接口org.apache.catalina.Lifecycle和一个枚举org.apache.catalina.LifecycleState来表示。

Lifecycle

org.apache.catalina.Lifecycle接口定义了组件的所有执行的动作,核心的有三个:

public interface Lifecycle {
    /** 第1类:针对监听器 **/
    // 添加监听器
    public void addLifecycleListener(LifecycleListener listener);
    // 获取所以监听器
    public LifecycleListener[] findLifecycleListeners();
    // 移除某个监听器
    public void removeLifecycleListener(LifecycleListener listener);
    
    /** 第2类:针对控制流程 **/
    // 初始化方法
    public void init() throws LifecycleException;
    // 启动方法
    public void start() throws LifecycleException;
    // 停止方法,和start对应
    public void stop() throws LifecycleException;
    // 销毁方法,和init对应
    public void destroy() throws LifecycleException;
    
    /** 第3类:针对状态 **/
    // 获取生命周期状态
    public LifecycleState getState();
    // 获取字符串类型的生命周期状态
    public String getStateName();
}

其中生命周期节点包括:

 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";

LifecycleState

状态机有下列分类

public enum LifecycleState {
    NEW(false, null),
    INITIALIZING(false, Lifecycle.BEFORE_INIT_EVENT),
    INITIALIZED(false, Lifecycle.AFTER_INIT_EVENT),
    STARTING_PREP(false, Lifecycle.BEFORE_START_EVENT),
    STARTING(true, Lifecycle.START_EVENT),
    STARTED(true, Lifecycle.AFTER_START_EVENT),
    STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT),
    STOPPING(false, Lifecycle.STOP_EVENT),
    STOPPED(false, Lifecycle.AFTER_STOP_EVENT),
    DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT),
    DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT),
    FAILED(false, null)
    }

枚举值表示状态
第一个参数表示当前状态下组件可不可用;
第二个参数表示当变为当前状态时发出相应的事件;

生命周期的流转状态如下所示:
在这里插入图片描述
1.所有的状态都能转变为failed;
2.一个组件在starting_prep,starting,started状态调用start()方法不会产生影响;
3.一个组件在new状态调用start方法时,会先调用init()方法;
4.一个组件在stoping_prep,stopping,stopped状态调用stop方法不会产生影响;
5.一个组件在new状态调用stop()方法时,会将状态直接改为stopped。当组件自己启动失败时,需要将子组件也进行停止,尽管某些子组件还没有启动;
6.其他状态互相转换都会抛出异常;
7.合法的状态转换发生时都会出发相应的lifecycleEvent事件,非法转换不会触发事件。

LifecycleBase

lifecycelBase是lifecycle的继承实现
在这里插入图片描述
生命周期监听器保存在一个线程安全的CopyOnWriteArrayList中。所以add和remove都是直接调用此List的相应方法。
findLifecycleListeners返回的是一个数组,为了线程安全,所以这会生成一个新数组。

public abstract class LifecycleBase implements Lifecycle {
    private static final Log log = LogFactory.getLog(LifecycleBase.class);
    private static final StringManager sm = StringManager.getManager(LifecycleBase.class);
    private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();
    private volatile LifecycleState state = LifecycleState.NEW;
   }
	@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);
	}

生命周期相关

  • init()
    @Override
    public final synchronized void init() throws LifecycleException {
    //如果不是new状态不允许调用init方法
        if (!state.equals(LifecycleState.NEW)) {
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
        }
        try {
        // 初始化逻辑之前,先将状态变更为`INITIALIZING`
        setStateInternal(LifecycleState.INITIALIZING, null, false);
        // 初始化,该方法为一个abstract方法,需要组件自行实现
        initInternal();
        // 初始化完成之后,状态变更为`INITIALIZED`
        setStateInternal(LifecycleState.INITIALIZED, null, false);
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.initFail", toString());
        }
    }

setStateInternal方法,可以看到这是一个私有方法,只能本类调用,

    private synchronized void setStateInternal(LifecycleState state, Object data, boolean check)
            throws LifecycleException {
 
        if (check) {
            if (state == null) {
            //空状态报异常
                invalidTransition("null");
            }
            // Any method can transition to failed
            // startInternal() permits STARTING_PREP to STARTING
            // stopInternal() permits STOPPING_PREP to STOPPING and FAILED to
            // STOPPING
            //任何状态都可以转为failed
            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))) {
                // No other transition permitted
                invalidTransition(state.name());
            }
        }
 // 设置状态
    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);
        }
    }

这里的 LifecycleListener 对象是在 Catalina 对象解析 server.xml 文件时就已经创建好并加到 lifecycleListeners 里的。

  • 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();
            //falied 执行stop方法
        } else if (state.equals(LifecycleState.FAILED)) {
            stop();    
            //不是`INITIALIZED`和`STOPPED`时,则说明是非法的操作      
        } else if (!state.equals(LifecycleState.INITIALIZED) &&
                !state.equals(LifecycleState.STOPPED)) {
            invalidTransition(Lifecycle.BEFORE_START_EVENT);
        }

        try {
 // start前的状态设置
        setStateInternal(LifecycleState.STARTING_PREP, null, false);
        // start逻辑,抽象方法,由组件自行实现
        startInternal();
        // start过程中,可能因为某些原因失败,这时需要stop操作
            if (state.equals(LifecycleState.FAILED)) {
                // This is a 'controlled' failure. The component put itself into the
                // FAILED state so call stop() to complete the clean-up.
                stop();
            } else if (!state.equals(LifecycleState.STARTING)) {
                // Shouldn't be necessary but acts as a check that sub-classes are
                // doing what they are supposed to.
                invalidTransition(Lifecycle.AFTER_START_EVENT);
            } else {
             // 设置状态为STARTED
                setStateInternal(LifecycleState.STARTED, null, false);
            }
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.startFail", toString());
        }
    }
  • stop()
@Override
public final synchronized void stop() throws LifecycleException {
    // `STOPPING_PREP`、`STOPPING`和STOPPED时,将忽略stop()的执行
    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;
    }
    // stop()的执行,必须要是`STARTED`和`FAILED`
    if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED)) {
        invalidTransition(Lifecycle.BEFORE_STOP_EVENT);
    }

    try {
        // `FAILED`时,直接触发BEFORE_STOP_EVENT事件
        if (state.equals(LifecycleState.FAILED)) {
  
            // fired
            fireLifecycleEvent(BEFORE_STOP_EVENT, null);
        } else {
            // 设置状态为STOPPING_PREP
            setStateInternal(LifecycleState.STOPPING_PREP, null, false);
        }
        // stop逻辑,抽象方法,组件自行实现
        stopInternal();
        if (!state.equals(LifecycleState.STOPPING) && !state.equals(LifecycleState.FAILED)) {
            invalidTransition(Lifecycle.AFTER_STOP_EVENT);
        }
        // 设置状态为STOPPED
        setStateInternal(LifecycleState.STOPPED, null, false);
    } catch (Throwable t) {
        ExceptionUtils.handleThrowable(t);
        setStateInternal(LifecycleState.FAILED, null, false);
        throw new LifecycleException(sm.getString("lifecycleBase.stopFail",toString()), t);
    } finally {
        if (this instanceof Lifecycle.SingleUse) {
            // Complete stop process first
            setStateInternal(LifecycleState.STOPPED, null, false);
            destroy();
        }
    }
}
  • destroy()
著作权归https://pdai.tech所有。
链接:https://pdai.tech/md/framework/tomcat/tomcat-x-lifecycle.html

@Override
public final synchronized void destroy() throws LifecycleException {
    // `FAILED`状态时,直接触发stop()逻辑
    if (LifecycleState.FAILED.equals(state)) {
        try {
            // Triggers clean-up
            stop();
        } catch (LifecycleException e) {
            // Just log. Still want to destroy.
            log.warn(sm.getString(
                    "lifecycleBase.destroyStopFail", toString()), e);
        }
    }

    // `DESTROYING`和`DESTROYED`时,忽略destroy的执行
    if (LifecycleState.DESTROYING.equals(state) ||
            LifecycleState.DESTROYED.equals(state)) {

        if (log.isDebugEnabled()) {
            Exception e = new LifecycleException();
            log.debug(sm.getString("lifecycleBase.alreadyDestroyed", toString()), e);
        } else if (log.isInfoEnabled() && !(this instanceof Lifecycle.SingleUse)) {
            // Rather than have every component that might need to call
            // destroy() check for SingleUse, don't log an info message if
            // multiple calls are made to destroy()
            log.info(sm.getString("lifecycleBase.alreadyDestroyed", toString()));
        }

        return;
    }

    // 非法状态判断
    if (!state.equals(LifecycleState.STOPPED) &&
            !state.equals(LifecycleState.FAILED) &&
            !state.equals(LifecycleState.NEW) &&
            !state.equals(LifecycleState.INITIALIZED)) {
        invalidTransition(Lifecycle.BEFORE_DESTROY_EVENT);
    }

    try {
        // destroy前状态设置
        setStateInternal(LifecycleState.DESTROYING, null, false);
       // 抽象方法,组件自行实现
        destroyInternal();
        // destroy后状态设置
        setStateInternal(LifecycleState.DESTROYED, null, false);
    } catch (Throwable t) {
        ExceptionUtils.handleThrowable(t);
        setStateInternal(LifecycleState.FAILED, null, false);
        throw new LifecycleException(
                sm.getString("lifecycleBase.destroyFail",toString()), t);
    }
}

Tomcat事件监听

事件监听的接口

public interface LifecycleListener {
    public void lifecycleEvent(LifecycleEvent event);
}

事件触发
tomcat每个组件的状态会发生变化,变化的时候会抛出一些事件,tomcat支持定义事件监听器来监听,并消费这些事件。
事件执行
事件监听功能的类为org.apache.catalina.util.LifecycleBase。每个组件都会集成这个类。该类有一个属性:List lifecycleListeners;该属性用来保存事件监听器,也就是说每个组件拥有一个事件监听器列表。
该类的方法:

  protected void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(this, type, data);
        for (LifecycleListener listener : lifecycleListeners) {
            listener.lifecycleEvent(event);
        }
    }

当组件状态变化时,会调用fireLifecycleEvent触发事件执行。比如当server的子类StandardServer启动时,会调用fireLifecycleEvent

  @Override
    protected void startInternal() throws LifecycleException {

        fireLifecycleEvent(CONFIGURE_START_EVENT, null);
        setState(LifecycleState.STARTING);

        globalNamingResources.start();

        // Start our defined Services
        synchronized (servicesLock) {
            for (Service service : services) {
                service.start();
            }
        }
    }

事件监听器
程序员可以自定义事件监听器,只需要实现lifecycleListener接口即可,比如:

class NamingListener implements lifecycleListener()
class FrameListener implements lifecyclelistener()

总结:这里的事件监听器,不是异步触发,而是主动调用事件监听器,这一点和nacos的事件触发器不同。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值