讲一下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的事件触发器不同。