Tomcat源碼分析 -- 3
sschrodinger
2018/12/19
參考
- 《深入剖析 Tomcat》 - 基于Tomcat 4.x
- 《Tomcat 架構(gòu)解析》劉光瑞 著
- 《大話設(shè)計(jì)模式》程杰 著
- Tomcat 8.5.x 源碼
tomcat 生命周期
如下圖所示,tomcat 組件的生命周期有如下的轉(zhuǎn)換方式。
tomcat 生命周期定義在枚舉類型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);
private final boolean available;
private final String lifecycleEvent;
private LifecycleState(boolean available, String lifecycleEvent) {
this.available = available;
this.lifecycleEvent = lifecycleEvent;
}
public boolean isAvailable() {
return available;
}
public String getLifecycleEvent() {
return lifecycleEvent;
}
}
note
- 枚舉的第一個參數(shù)代表改組件是否可用
- 枚舉的第二個參數(shù)代表生命周期事件
在 tomcat 中摸恍,所有的組件都有父接口Lifecycle
,接口相關(guān)定義如下:
public interface Lifecycle {
// ...
// ...
public void init() throws LifecycleException;
public void start() throws LifecycleException;
public void stop() throws LifecycleException;
public void destroy() throws LifecycleException;
public LifecycleState getState();
public String getStateName();
//...
}
tomcat 使用LifecycleBase
這個抽象類來實(shí)現(xiàn)狀態(tài)的轉(zhuǎn)換函數(shù)绷柒,所有的組件不直接繼承于lifecycle
,而是直接繼承于lifecycleBase
這個抽象類。抽象類部分代碼如下:
ublic abstract class LifecycleBase implements Lifecycle {
private volatile LifecycleState state = LifecycleState.NEW;
@Override
public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
try {
setStateInternal(LifecycleState.INITIALIZING, null, false);
initInternal();
setStateInternal(LifecycleState.INITIALIZED, null, false);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(
sm.getString("lifecycleBase.initFail",toString()), t);
}
}
protected abstract void initInternal() throws LifecycleException;
@Override
public final synchronized void start() throws LifecycleException {
if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
LifecycleState.STARTED.equals(state)) {
if (log.isDebugEnabled()) {
Exception e = new LifecycleException();
log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
} else if (log.isInfoEnabled()) {
log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
}
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);
}
try {
setStateInternal(LifecycleState.STARTING_PREP, null, false);
startInternal();
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 {
setStateInternal(LifecycleState.STARTED, null, false);
}
} catch (Throwable t) {
// This is an 'uncontrolled' failure so put the component into the
// FAILED state and throw an exception.
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(sm.getString("lifecycleBase.startFail", toString()), t);
}
}
@Override
public final synchronized void stop() throws LifecycleException {
if (LifecycleState.STOPPING_PREP.equals(state) || LifecycleState.STOPPING.equals(state) ||
LifecycleState.STOPPED.equals(state)) {
if (log.isDebugEnabled()) {
Exception e = new LifecycleException();
log.debug(sm.getString("lifecycleBase.alreadyStopped", toString()), e);
} else if (log.isInfoEnabled()) {
log.info(sm.getString("lifecycleBase.alreadyStopped", toString()));
}
return;
}
if (state.equals(LifecycleState.NEW)) {
state = LifecycleState.STOPPED;
return;
}
if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED)) {
invalidTransition(Lifecycle.BEFORE_STOP_EVENT);
}
try {
if (state.equals(LifecycleState.FAILED)) {
// Don't transition to STOPPING_PREP as that would briefly mark the
// component as available but do ensure the BEFORE_STOP_EVENT is
// fired
fireLifecycleEvent(BEFORE_STOP_EVENT, null);
} else {
setStateInternal(LifecycleState.STOPPING_PREP, null, false);
}
stopInternal();
// Shouldn't be necessary but acts as a check that sub-classes are
// doing what they are supposed to.
if (!state.equals(LifecycleState.STOPPING) && !state.equals(LifecycleState.FAILED)) {
invalidTransition(Lifecycle.AFTER_STOP_EVENT);
}
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();
}
}
}
protected abstract void stopInternal() throws LifecycleException;
@Override
public final synchronized void destroy() throws LifecycleException {
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);
}
}
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 {
setStateInternal(LifecycleState.DESTROYING, null, false);
destroyInternal();
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);
}
}
protected abstract void destroyInternal() throws LifecycleException;
@Override
public LifecycleState getState() {
return state;
}
@Override
public String getStateName() {
return getState().toString();
}
protected synchronized void setState(LifecycleState state)
throws LifecycleException {
setStateInternal(state, null, true);
}
protected synchronized void setState(LifecycleState state, Object data)
throws LifecycleException {
setStateInternal(state, data, true);
}
private synchronized void setStateInternal(LifecycleState state,
Object data, boolean check) throws LifecycleException {
if (log.isDebugEnabled()) {
log.debug(sm.getString("lifecycleBase.setState", this, state));
}
if (check) {
// Must have been triggered by one of the abstract methods (assume
// code in this class is correct)
// null is never a valid state
if (state == null) {
invalidTransition("null");
// Unreachable code - here to stop eclipse complaining about
// a possible NPE further down the method
return;
}
// Any method can transition to failed
// startInternal() permits STARTING_PREP to STARTING
// stopInternal() permits STOPPING_PREP to STOPPING and FAILED to
// STOPPING
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);
}
}
private void invalidTransition(String type) throws LifecycleException {
String msg = sm.getString("lifecycleBase.invalidTransition", type,
toString(), state);
throw new LifecycleException(msg);
}
}
代碼冗長幔摸,但是實(shí)現(xiàn)功能簡單,實(shí)現(xiàn)了一個類似于有限狀態(tài)自動機(jī)的轉(zhuǎn)換邏輯颤练。
從init()
函數(shù)入手既忆,首先檢查當(dāng)前組件狀態(tài),如果狀態(tài)不為 LifecycleState.NEW
嗦玖,則拋出一個錯誤患雇,否則,將當(dāng)前狀態(tài)更新為LifecycleState.INITIALIZING
宇挫,并且執(zhí)行抽象函數(shù)initInternal()
苛吱,完成抽象函數(shù)的執(zhí)行后,將當(dāng)前狀態(tài)更新為LifecycleState.INITIALIZED
器瘪。
start()
又谋,stop()
,desdroy()
函數(shù)和init()
函數(shù)使用流程基本相似娱局,但是應(yīng)用邏輯更加復(fù)雜彰亥。同時引入了startInternal()
,stopInternal()
衰齐,desdroyInternal()
三個方法以供重寫任斋。
所以,lifecyleBase
類,實(shí)現(xiàn)了模板方法模式废酷,組件只需要重寫initInternal()
瘟檩,startInternal()
,stopInternal()
澈蟆,desdroyInternal()
四個方法墨辛,來完成具體的步驟,比如說數(shù)據(jù)庫初始化等操作趴俘。
舉個例子睹簇,我們知道 tomcat 組件可以實(shí)現(xiàn)父組件啟動,就啟動所有子組件的功能寥闪,同時也可以執(zhí)行后臺程序太惠,這些所有的邏輯程序都在組件的父類型ContainerBase
中實(shí)現(xiàn),關(guān)鍵代碼如下:
public abstract class ContainerBase extends LifecycleMBeanBase implements Container {
//保存子組件
protected final HashMap<String, Container> children = new HashMap<>();
//后臺執(zhí)行間隔事件疲憋,-1代表不執(zhí)行
protected int backgroundProcessorDelay = -1;
//后臺程序線程
private Thread thread = null;
//組件執(zhí)行線程
protected ThreadPoolExecutor startStopExecutor;
@Override
protected void initInternal() throws LifecycleException {
BlockingQueue<Runnable> startStopQueue = new LinkedBlockingQueue<>();
startStopExecutor = new ThreadPoolExecutor(
getStartStopThreadsInternal(),
getStartStopThreadsInternal(), 10, TimeUnit.SECONDS,
startStopQueue,
new StartStopThreadFactory(getName() + "-startStop-"));
startStopExecutor.allowCoreThreadTimeOut(true);
super.initInternal();
}
@Override
protected synchronized void startInternal() throws LifecycleException {
// Start our subordinate components, if any
logger = null;
getLogger();
Cluster cluster = getClusterInternal();
if (cluster instanceof Lifecycle) {
((Lifecycle) cluster).start();
}
Realm realm = getRealmInternal();
if (realm instanceof Lifecycle) {
((Lifecycle) realm).start();
}
// Start our child containers, if any
Container children[] = findChildren();
List<Future<Void>> results = new ArrayList<>();
for (int i = 0; i < children.length; i++) {
results.add(startStopExecutor.submit(new StartChild(children[i])));
}
MultiThrowable multiThrowable = null;
for (Future<Void> result : results) {
try {
result.get();
} catch (Throwable e) {
log.error(sm.getString("containerBase.threadedStartFailed"), e);
if (multiThrowable == null) {
multiThrowable = new MultiThrowable();
}
multiThrowable.add(e);
}
}
if (multiThrowable != null) {
throw new LifecycleException(sm.getString("containerBase.threadedStartFailed"),
multiThrowable.getThrowable());
}
// Start the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).start();
}
setState(LifecycleState.STARTING);
// Start our thread
threadStart();
}
@Override
protected synchronized void stopInternal() throws LifecycleException {
// Stop our thread
threadStop();
setState(LifecycleState.STOPPING);
// Stop the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle &&
((Lifecycle) pipeline).getState().isAvailable()) {
((Lifecycle) pipeline).stop();
}
// Stop our child containers, if any
Container children[] = findChildren();
List<Future<Void>> results = new ArrayList<>();
for (int i = 0; i < children.length; i++) {
results.add(startStopExecutor.submit(new StopChild(children[i])));
}
boolean fail = false;
for (Future<Void> result : results) {
try {
result.get();
} catch (Exception e) {
log.error(sm.getString("containerBase.threadedStopFailed"), e);
fail = true;
}
}
if (fail) {
throw new LifecycleException(
sm.getString("containerBase.threadedStopFailed"));
}
// Stop our subordinate components, if any
Realm realm = getRealmInternal();
if (realm instanceof Lifecycle) {
((Lifecycle) realm).stop();
}
Cluster cluster = getClusterInternal();
if (cluster instanceof Lifecycle) {
((Lifecycle) cluster).stop();
}
}
@Override
protected void destroyInternal() throws LifecycleException {
Realm realm = getRealmInternal();
if (realm instanceof Lifecycle) {
((Lifecycle) realm).destroy();
}
Cluster cluster = getClusterInternal();
if (cluster instanceof Lifecycle) {
((Lifecycle) cluster).destroy();
}
// Stop the Valves in our pipeline (including the basic), if any
if (pipeline instanceof Lifecycle) {
((Lifecycle) pipeline).destroy();
}
// Remove children now this container is being destroyed
for (Container child : findChildren()) {
removeChild(child);
}
// Required if the child is destroyed directly.
if (parent != null) {
parent.removeChild(this);
}
// If init fails, this may be null
if (startStopExecutor != null) {
startStopExecutor.shutdownNow();
}
super.destroyInternal();
}
@Override
public void backgroundProcess() {
if (!getState().isAvailable())
return;
Cluster cluster = getClusterInternal();
if (cluster != null) {
try {
cluster.backgroundProcess();
} catch (Exception e) {
log.warn(sm.getString("containerBase.backgroundProcess.cluster",
cluster), e);
}
}
Realm realm = getRealmInternal();
if (realm != null) {
try {
realm.backgroundProcess();
} catch (Exception e) {
log.warn(sm.getString("containerBase.backgroundProcess.realm", realm), e);
}
}
Valve current = pipeline.getFirst();
while (current != null) {
try {
current.backgroundProcess();
} catch (Exception e) {
log.warn(sm.getString("containerBase.backgroundProcess.valve", current), e);
}
current = current.getNext();
}
fireLifecycleEvent(Lifecycle.PERIODIC_EVENT, null);
}
protected void threadStart() {
if (thread != null)
return;
if (backgroundProcessorDelay <= 0)
return;
threadDone = false;
String threadName = "ContainerBackgroundProcessor[" + toString() + "]";
thread = new Thread(new ContainerBackgroundProcessor(), threadName);
thread.setDaemon(true);
thread.start();
}
}
initInternal()
的作用是創(chuàng)建一個可執(zhí)行的線程池凿渊。
``startInternal()`的作用是啟動自身及其子組件「苛看如下代碼:
Container children[] = findChildren();
List<Future<Void>> results = new ArrayList<>();
for (int i = 0; i < children.length; i++) {
results.add(startStopExecutor.submit(new StartChild(children[i])));
}
以上代碼截取自函數(shù)內(nèi)部埃脏,通過findChildren()
獲得所有的子組件,然后在線程池中啟動子組件秋忙。其中彩掐,StartChild
有如下定義:
private static class StartChild implements Callable<Void> {
private Container child;
public StartChild(Container child) {
this.child = child;
}
@Override
public Void call() throws LifecycleException {
child.start();
return null;
}
}
Container
類直接實(shí)現(xiàn)接口Lifecycle
,一般子組件都會直接繼承于containnerBase
翰绊,即一般組件都會間接繼承LifecycleBase
類佩谷,則調(diào)用StartChild
類的call()
方法旁壮,會間接的調(diào)用LifecycleBase
實(shí)現(xiàn)的start()
方法监嗜,遞歸的啟動所有的組件。
在startInternal()
方法后抡谐,有一函數(shù)threadStart()
裁奇,該函數(shù)負(fù)責(zé)啟動后臺線程。
具體實(shí)現(xiàn)如下:
protected void threadStart() {
if (thread != null)
return;
if (backgroundProcessorDelay <= 0)
return;
threadDone = false;
String threadName = "ContainerBackgroundProcessor[" + toString() + "]";
thread = new Thread(new ContainerBackgroundProcessor(), threadName);
thread.setDaemon(true);
thread.start();
}
將后臺線程執(zhí)行代碼backgroundProcess()
注冊到ContainerBackgroundProcessor
中麦撵,保證周期性的執(zhí)行后臺程序刽肠。
note
ContainerBackgroundProcesor
將符合要求的子組件的后臺程序打包運(yùn)行,即用同一個線程執(zhí)行多個后臺程序免胃,可以節(jié)約資源
tomcat 事件機(jī)制
重新回到Lifecycle
接口定義音五,定義剩下部分如下:
public interface Lifecycle {
// ----------------------------------------------------- Manifest Constants
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";
// --------------------------------------------------------- Public Methods
public void addLifecycleListener(LifecycleListener listener);
public LifecycleListener[] findLifecycleListeners();
public void removeLifecycleListener(LifecycleListener listener);
}
我們發(fā)現(xiàn),在Lifecycle
中定義了13種事件變量羔沙。前面10種變量和生命周期狀態(tài)一一映射(LifecycleState
枚舉類型的第二個參數(shù))躺涝。
LifecycleListener
為監(jiān)聽者,當(dāng)有事件到來時扼雏,執(zhí)行lifecycleEvent
函數(shù)坚嗜。形式如下:
public interface LifecycleListener {
public void lifecycleEvent(LifecycleEvent event);
}
其中LifecycleEvent
封裝了事件名稱和發(fā)出事件的組件夯膀。
在lifecycleBase
中,實(shí)現(xiàn)了增加監(jiān)聽者和移除監(jiān)聽者的函數(shù)苍蔬,函數(shù)如下:
public abstract class LifecycleBase implements Lifecycle {
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);
}
//執(zhí)行所有的監(jiān)聽者函數(shù)
protected void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(this, type, data);
for (LifecycleListener listener : lifecycleListeners) {
listener.lifecycleEvent(event);
}
}
//...
}
查看LifecycleBase
诱建,我們來看具體怎么實(shí)現(xiàn)事件通知機(jī)制。LifecycleBase
的init()
函數(shù)部分如下:
try {
setStateInternal(LifecycleState.INITIALIZING, null, false);
initInternal();
setStateInternal(LifecycleState.INITIALIZED, null, false);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(
sm.getString("lifecycleBase.initFail",toString()), t);
}
可以看到碟绑,函數(shù)通過setStateInternal
來改變其生命周期俺猿,當(dāng)生命周期改變,一定會導(dǎo)致事件的發(fā)生蜈敢,我們看setStateInternal
的源碼辜荠,關(guān)鍵源碼如下:
private synchronized void setStateInternal(LifecycleState state,
Object data, boolean check) throws LifecycleException {
//...
this.state = state;
String lifecycleEvent = state.getLifecycleEvent();
if (lifecycleEvent != null) {
fireLifecycleEvent(lifecycleEvent, data);
}
}
可以看到,在生命周期改變的時候抓狭,自動向事件監(jiān)聽者發(fā)送消息伯病,供事件監(jiān)聽者處理。
note
- 除了與事件綁定的10個事件外否过,還有一個周期性事件午笛、配置啟動事件與配置停止事件,使用方法類似苗桂。