美文网首页
Tomcat源码分析 -- 3

Tomcat源码分析 -- 3

作者: sschrodinger | 来源:发表于2019-03-07 14:54 被阅读0次

    Tomcat源码分析 -- 3

    sschrodinger

    2018/12/19


    参考


    • 《深入剖析 Tomcat》 - 基于Tomcat 4.x
    • 《Tomcat 架构解析》刘光瑞 著
    • 《大话设计模式》程杰 著
    • Tomcat 8.5.x 源码

    tomcat 生命周期


    如下图所示,tomcat 组件的生命周期有如下的转换方式。

    tomcat 生命周期

    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

    • 枚举的第一个参数代表改组件是否可用
    • 枚举的第二个参数代表生命周期事件

    在 tomcat 中,所有的组件都有父接口Lifecycle,接口相关定义如下:

    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这个抽象类来实现状态的转换函数,所有的组件不直接继承于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);
        }
    }
    

    代码冗长,但是实现功能简单,实现了一个类似于有限状态自动机的转换逻辑。

    init()函数入手,首先检查当前组件状态,如果状态不为 LifecycleState.NEW,则抛出一个错误,否则,将当前状态更新为LifecycleState.INITIALIZING,并且执行抽象函数initInternal(),完成抽象函数的执行后,将当前状态更新为LifecycleState.INITIALIZED

    start()stop()desdroy()函数和init()函数使用流程基本相似,但是应用逻辑更加复杂。同时引入了startInternal()stopInternal()desdroyInternal()三个方法以供重写。

    所以,lifecyleBase类,实现了模板方法模式,组件只需要重写initInternal()startInternal()stopInternal()desdroyInternal()四个方法,来完成具体的步骤,比如说数据库初始化等操作。

    举个例子,我们知道 tomcat 组件可以实现父组件启动,就启动所有子组件的功能,同时也可以执行后台程序,这些所有的逻辑程序都在组件的父类型ContainerBase中实现,关键代码如下:

    public abstract class ContainerBase extends LifecycleMBeanBase  implements Container {
    
        //保存子组件
        protected final HashMap<String, Container> children = new HashMap<>();
    
        //后台执行间隔事件,-1代表不执行
        protected int backgroundProcessorDelay = -1;
        
        //后台程序线程
        private Thread thread = null;
        
        //组件执行线程
        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()的作用是创建一个可执行的线程池。

    ``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])));
    }
    

    以上代码截取自函数内部,通过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类直接实现接口Lifecycle,一般子组件都会直接继承于containnerBase,即一般组件都会间接继承LifecycleBase类,则调用StartChild类的call()方法,会间接的调用LifecycleBase实现的start()方法,递归的启动所有的组件。

    startInternal()方法后,有一函数threadStart(),该函数负责启动后台线程。
    具体实现如下:

    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();
    
    }
    

    将后台线程执行代码backgroundProcess()注册到ContainerBackgroundProcessor中,保证周期性的执行后台程序。

    note

    • ContainerBackgroundProcesor将符合要求的子组件的后台程序打包运行,即用同一个线程执行多个后台程序,可以节约资源

    tomcat 事件机制


    重新回到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);
    }
    

    我们发现,在Lifecycle中定义了13种事件变量。前面10种变量和生命周期状态一一映射(LifecycleState枚举类型的第二个参数)。

    LifecycleListener为监听者,当有事件到来时,执行lifecycleEvent函数。形式如下:

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

    其中LifecycleEvent封装了事件名称和发出事件的组件。

    lifecycleBase中,实现了增加监听者和移除监听者的函数,函数如下:

    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);
        }
        
        //执行所有的监听者函数
        protected void fireLifecycleEvent(String type, Object data) {
            LifecycleEvent event = new LifecycleEvent(this, type, data);
            for (LifecycleListener listener : lifecycleListeners) {
                listener.lifecycleEvent(event);
            }
        }
        
        //...
    }
    

    查看LifecycleBase,我们来看具体怎么实现事件通知机制。LifecycleBaseinit()函数部分如下:

    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);
    }
    

    可以看到,函数通过setStateInternal来改变其生命周期,当生命周期改变,一定会导致事件的发生,我们看setStateInternal的源码,关键源码如下:

    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);
        }
    }
    

    可以看到,在生命周期改变的时候,自动向事件监听者发送消息,供事件监听者处理。

    note

    • 除了与事件绑定的10个事件外,还有一个周期性事件、配置启动事件与配置停止事件,使用方法类似。

    相关文章

      网友评论

          本文标题:Tomcat源码分析 -- 3

          本文链接:https://www.haomeiwen.com/subject/rvvcpqtx.html