美文网首页
Tomcat源码解析-组件之StandardService

Tomcat源码解析-组件之StandardService

作者: 贪睡的企鹅 | 来源:发表于2019-08-09 16:36 被阅读0次

    1 StandardService职责

    StandardService是tomcat容器最高层组件StandardService的子组件,主要职责是管理子程组件Connector,Engine,Mapper,Executor。

    image

    2 解析server.xml

    Tomcat使用Digester解析server.xml,Digester是一款用于将xml转换为Java对象的事件驱动型工具,是对SAX的高层次的封装。相对于SAX,Digester可以针对每一个xml标签设置对应的解析规则。详见 Tomcat相关技术-Digester(二)

    Tomcat在Catalina组件初始化阶段调用createStartDigester()创建Digester对象,Digester对象内包含解析server.xml规则,接着通过Digester对象解析server.xml实例化StandardService,并对部分属性设置值。

    server.xml配置

    <Service name="Catalina">
    
        <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" socket.soKeepAlive="true"/>
        
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    
        <Engine name="Catalina" defaultHost="localhost">
    
          <Realm className="org.apache.catalina.realm.LockOutRealm">
           
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
          </Realm>
    
          <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true">
    
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log" suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
          </Host>
        </Engine>
      </Service>
    
    2.1 解析<Service>标签
        //解析<Server><Service>标签
        /** 解析<Service>标签实例化StandardService对象,并push到操作栈中 **/
        digester.addObjectCreate("Server/Service",
                                 "org.apache.catalina.core.StandardService",
                                 "className");
                                 
        /** 解析<Service>标签将标签中属性值映射到栈顶StandardService对象中**/
        digester.addSetProperties("Server/Service");
        
        /** 解析</Service>标签将操作栈栈顶对象作为次栈顶对象StandardServer.addService方法调用的参数,设置到StandardServer.service属性中**/
        digester.addSetNext("Server/Service",
                            "addService",
                            "org.apache.catalina.Service");
    
    2.2 解析<Listener>标签
        //解析<Server><Service><Listener>标签
        /** 解析<Listener>标签实例化标签中className属性定义的对象,并push到操作栈中 **/
        digester.addObjectCreate("Server/Service/Listener",
                                 null, 
                                 "className");
                                 
        /** 解析<Listener>标签将标签中属性值映射到其实例化对象中**/
        digester.addSetProperties("Server/Service/Listener");
        
        
        /** 解析</Listener>标签将操作栈栈顶对象作为次栈顶对象StandardService.addLifecycleListener方法调用的参数,即将<Server><Service><Listener>标签实例化的监听器添对象加到StandardService组件生命周期监听器列表中**/
        digester.addSetNext("Server/Service/Listener",
                            "addLifecycleListener",
                            "org.apache.catalina.LifecycleListener");
                            
    

    添加一个生命周期监听器

        public abstract class LifecycleBase implements Lifecycle {
            ...省略代码
        
            /**
             * 管理当前组件生命周期监听器列表
             */
            private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();
            
            /**
             * 给当前组件添加一个生命周期监听器
             */
            @Override
            public void addLifecycleListener(LifecycleListener listener) {
                lifecycleListeners.add(listener);
            }
            ...省略代码
    
    2.3 解析<Executor>标签
            //解析<Server><Service><Executor>标签
            /** 解析<Executor>标签实例化StandardThreadExecutor对象,并push到操作栈中 **/
            digester.addObjectCreate("Server/Service/Executor",
                             "org.apache.catalina.core.StandardThreadExecutor",
                             "className");
                             
            /** 解析<Executor>标签将标签中属性值映射到其实例化对象中**/
            digester.addSetProperties("Server/Service/Executor");
            
            /** 解析</Executor>标签将操作栈栈顶对象作为次栈顶对象StandardService.addExecutor方法调用的参数,即将StandardThreadExecutor对象加到StandardService组件线程池组件列表中**/
            digester.addSetNext("Server/Service/Executor",
                                    "addExecutor",
                                "org.apache.catalina.Executor");
    

    添加线程池子组件

        /**
         * 向Service组件添加线程池
         * Executor 扩展了线程池,作为tomcat的一个组件
         */
        @Override
        public void addExecutor(Executor ex) {
            synchronized (executors) {
                if (!executors.contains(ex)) {
                    executors.add(ex);
    
                    /** 如果当前Service组件已经启动,则启动 线程池 组件 **/
                    if (getState().isAvailable()) {
                        try {
                            ex.start();
                        } catch (LifecycleException x) {
                            log.error("Executor.start", x);
                        }
                    }
                }
            }
        }
    
    

    2.4 解析<Connector>标签

        //解析<Server><Service><Connector>标签
        /** 解析<Connector>标签使用自定义规则ConnectorCreateRule**/
        digester.addRule("Server/Service/Connector",
                         new ConnectorCreateRule());
                         
        /** 解析<Connector>标签属性使用自定义规则SetAllPropertiesRule**/
        digester.addRule("Server/Service/Connector",
                         new SetAllPropertiesRule(new String[]{"executor", "sslImplementationName"}));
        
        /** 解析</Connector>标签将操作栈栈顶对象作为次栈顶对象StandardService.addConnector方法调用的参数,即将Connector对象加到StandardService组件Connector数组中**/
        digester.addSetNext("Server/Service/Connector",
                            "addConnector",
                            "org.apache.catalina.connector.Connector");
    

    ConnectorCreateRule规则解析器

    /**
     * 解析<Connector>规则处理器
     */
    public class ConnectorCreateRule extends Rule {
    
        private static final Log log = LogFactory.getLog(ConnectorCreateRule.class);
        protected static final StringManager sm = StringManager.getManager(ConnectorCreateRule.class);
        // --------------------------------------------------------- Public Methods
    
    
        /**
         * 解析<Server><Service><Connector>回调处理逻辑
         */
        @Override
        public void begin(String namespace, String name, Attributes attributes)
                throws Exception {
            /** 获取栈顶对象svc **/
            Service svc = (Service)digester.peek();
            Executor ex = null;
    
            /** 如果<Server><Service><Connector>标签存在executor属性,则从Service组件获取该属性值对应连接池ex**/
            if ( attributes.getValue("executor")!=null ) {
                ex = svc.getExecutor(attributes.getValue("executor"));
            }
            /** 实例化Connector组件 **/
            Connector con = new Connector(attributes.getValue("protocol"));
            if (ex != null) {
                /** 使用反射技术将连接池设置给ProtocolHandler组件executor属性  **/
                setExecutor(con, ex);
            }
    
            /** 获取<Server><Service><Connector>标签sslImplementationName属性 **/
            String sslImplementationName = attributes.getValue("sslImplementationName");
            if (sslImplementationName != null) {
                /** 使用反射技术将连接池设置给ProtocolHandler组件sslImplementationName属性  **/
                setSSLImplementationName(con, sslImplementationName);
            }
            digester.push(con);
        }
    
        /**
         * 使用反射技术将连接池设置给ProtocolHandler组件executor属性
         */
        private static void setExecutor(Connector con, Executor ex) throws Exception {
            Method m = IntrospectionUtils.findMethod(con.getProtocolHandler().getClass(),"setExecutor",new Class[] {java.util.concurrent.Executor.class});
            if (m!=null) {
                m.invoke(con.getProtocolHandler(), new Object[] {ex});
            }else {
                log.warn(sm.getString("connector.noSetExecutor", con));
            }
        }
    
        /**
         * 使用反射技术将连接池设置给ProtocolHandler组件sslImplementationName属性
         */
        private static void setSSLImplementationName(Connector con, String sslImplementationName) throws Exception {
            Method m = IntrospectionUtils.findMethod(con.getProtocolHandler().getClass(),"setSslImplementationName",new Class[] {String.class});
            if (m != null) {
                m.invoke(con.getProtocolHandler(), new Object[] {sslImplementationName});
            } else {
                log.warn(sm.getString("connector.noSetSSLImplementationName", con));
            }
        }
    
        /**
         * 解析<Server><Service></Connector>回调处理逻辑
         */
        @Override
        public void end(String namespace, String name) throws Exception {
            digester.pop();
        }
    }
    

    添加线程池子组件

    /**
         * 为Service组件添加 Connector子组件
         */
        @Override
        public void addConnector(Connector connector) {
    
            synchronized (connectorsLock) {
                /** connector 反向关联父组件 Service **/
                connector.setService(this);
    
                /** 将Connector组件添加到Service 组件的connectors数组类型属性connectors中 **/
                Connector results[] = new Connector[connectors.length + 1];
                System.arraycopy(connectors, 0, results, 0, connectors.length);
                results[connectors.length] = connector;
                connectors = results;
    
                /** 如果当前Service组件正在运行,则启动添加Connector 组件 **/
                if (getState().isAvailable()) {
                    try {
                        connector.start();
                    } catch (LifecycleException e) {
                        log.error(sm.getString(
                                "standardService.connector.startFailed",
                                connector), e);
                    }
                }
    
                /** 将connector属性更改通知给监听器  **/
                support.firePropertyChange("connector", null, connector);
            }
        }
    
    2.5 解析<Engine>标签
        // 解析<Server><Service>子标签,设置EngineRuleSet作为解析规则组
        digester.addRuleSet(new EngineRuleSet("Server/Service/"));
    

    EngineRuleSet

    public class EngineRuleSet extends RuleSetBase {
    
        protected final String prefix;
    
        public EngineRuleSet() {
            this("");
        }
    
        public EngineRuleSet(String prefix) {
            this.prefix = prefix;
        }
            @Override
        public void addRuleInstances(Digester digester) {
    
            /** 解析<Engine>标签实例化StandardEngine对象,并push到操作栈中 **/
            digester.addObjectCreate(prefix + "Engine",
                                     "org.apache.catalina.core.StandardEngine",
                                     "className");
    
            /** 解析<Engine>标签将标签中属性值映射到其实例化对象中**/
            digester.addSetProperties(prefix + "Engine");
    
            /** 解析<Engine>标签使用自定义规则SLifecycleListenerRule**/
            digester.addRule(prefix + "Engine",
                             new LifecycleListenerRule
                             ("org.apache.catalina.startup.EngineConfig",
                              "engineConfigClass"));
    
            /** 解析<Engine>标签将操作栈栈顶对象作为次栈顶对象StandardService.setContainer方法调用的参数,设置到StandardServer属性中**/
            digester.addSetNext(prefix + "Engine",
                                "setContainer",
                                "org.apache.catalina.Engine");
    

    添加Engine子组件

        @Override
        public void setContainer(Engine engine) {
            /** 获取原始Engine组件引用 **/
            Engine oldEngine = this.engine;
            if (oldEngine != null) {
                oldEngine.setService(null);
            }
            /** 设置engine **/
            this.engine = engine;
            if (this.engine != null) {
                this.engine.setService(this);
            }
            /** 如果StandardService组件运行,则启动添加engine组件,并重启MapperListener**/
            if (getState().isAvailable()) {
                if (this.engine != null) {
                    try {
                        this.engine.start();
                    } catch (LifecycleException e) {
                        log.warn(sm.getString("standardService.engine.startFailed"), e);
                    }
                }
                // Restart MapperListener to pick up new engine.
                try {
                    mapperListener.stop();
                } catch (LifecycleException e) {
                    log.warn(sm.getString("standardService.mapperListener.stopFailed"), e);
                }
                try {
                    mapperListener.start();
                } catch (LifecycleException e) {
                    log.warn(sm.getString("standardService.mapperListener.startFailed"), e);
                }
                if (oldEngine != null) {
                    try {
                        oldEngine.stop();
                    } catch (LifecycleException e) {
                        log.warn(sm.getString("standardService.engine.stopFailed"), e);
                    }
                }
            }
        
            /** 将Engine属性更改通知给监听器  **/
            support.firePropertyChange("container", oldEngine, this.engine);
        }
    

    3 StandardService生命周期

    3.1 Lifecycle接口

    tomcat中所有组件都实现了Lifecycle 接口。

    public interface Lifecycle {
        ....
        // 初始化方法
        public void init() throws LifecycleException;
        // 启动方法
        public void start() throws LifecycleException;
        // 停止方法,和start对应
        public void stop() throws LifecycleException;
        // 销毁方法,和init对应
        public void destroy() throws LifecycleException;
        // 获取生命周期状态
        public LifecycleState getState();
        // 获取字符串类型的生命周期状态
        public String getStateName();
    }
    
    3.2 LifecycleBase基类

    Tomcat 定义一个基类LifecycleBase 来实现 Lifecycle 接口,把一些公共的逻辑放到基类中去,比如生命状态的转变与维护、生命事件的触发以及监听器的添加和删除等,而子类就负责实现自己的初始化、启动和停止等模板方法。为了避免跟基类中的方法同名,我们把具体子类的实现方法改个名字,在后面加上 Internal,叫 initInternal、startInternal 等。

    这里以init()方法为例子来了解下LifecycleBase基类。如果需要查看比较详细详见 Tomcat架构设计-组件生命周期

    /**
     *  组件初始化动作,所有组件通用操作
     *   1 检查校验当前组件状态是否能够初始化
     *   2 修改当前的状态从 NEW-->INITIALIZING
     *   3 调用每个组件模板方法实现完成初始化动作
     *   4 修改当前的状态从 INITIALIZING-->INITIALIZED
     */
    @Override
    public final synchronized void init() throws LifecycleException {
        /** 非NEW状态,不允许调用init()方法 **/
        if (!state.equals(LifecycleState.NEW)) {
            /** 从sm获取"lifecycleBase.invalidTransition"属性对应日志格式,抛出LifecycleException异常 **/
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
        }
    
        try {
            /** 初始化逻辑之前,将状态变更为`INITIALIZING` **/
            setStateInternal(LifecycleState.INITIALIZING, null, false);
            /** 初始化组件,该方法为一个abstract模板方法,需要组件自行实现  **/
            initInternal();
            /** 初始化完成之后,状态变更为`INITIALIZED`  **/
            setStateInternal(LifecycleState.INITIALIZED, null, false);
        }
        /** 初始化的过程中,可能会有异常抛出,这时需要捕获异常,并将状态变更为`FAILED` **/
        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;
    
    

    其他模板方法

    /**
     * 启动模板方法
     */
    protected abstract void startInternal() throws LifecycleException;
    
    /**
     * 停止模板方法
     */
    protected abstract void stopInternal() throws LifecycleException;
        
    /**
     * 销毁模板方法
     */
    protected abstract void destroyInternal() throws LifecycleException;
    
    3.2 初始化StandardService组件
     @Override
    protected void initInternal() throws LifecycleException {
    
    
        super.initInternal();
    
        /** 初始化engine 子组件 **/
        if (engine != null) {
            engine.init();
        }
    
        /** 初始化所有Executor 子组件 **/
        for (Executor executor : findExecutors()) {
            if (executor instanceof JmxEnabled) {
                ((JmxEnabled) executor).setDomain(getDomain());
            }
            executor.init();
        }
    
        /** 初始化mapperListener 子组件 **/
        mapperListener.init();
    
    
        /** 初始化所有Connector 子组件 **/
        synchronized (connectorsLock) {
            for (Connector connector : connectors) {
                try {
                    connector.init();
                } catch (Exception e) {
                    String message = sm.getString(
                            "standardService.connector.initFailed", connector);
                    log.error(message, e);
    
                    if (Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE"))
                        throw new LifecycleException(message);
                }
            }
        }
    }
    
    3.3 启动StandardService组件
    @Override
    protected void startInternal() throws LifecycleException {
    
        if(log.isInfoEnabled())
            log.info(sm.getString("standardService.start.name", this.name));
    
        /** 更正当前组件状态为STARTING  **/
        setState(LifecycleState.STARTING);
    
        /** 启动engine 子组件 **/
        if (engine != null) {
            synchronized (engine) {
                engine.start();
            }
        }
    
        /** 启动所有Executor 子组件 **/
        synchronized (executors) {
            for (Executor executor: executors) {
                executor.start();
            }
        }
    
        /** 启动mapperListener 子组件 **/
        mapperListener.start();
    
        /** 启动所有Connector 子组件 **/
        synchronized (connectorsLock) {
            for (Connector connector: connectors) {
                try {
                    // If it has already failed, don't try and start it
                    if (connector.getState() != LifecycleState.FAILED) {
                        connector.start();
                    }
                } catch (Exception e) {
                    log.error(sm.getString(
                            "standardService.connector.startFailed",
                            connector), e);
                }
            }
        }
    }
    
    3.4 停止StandardService组件
    @Override
    protected void stopInternal() throws LifecycleException {
    
        /** 暂停所有Connector 子组件 **/
        synchronized (connectorsLock) {
            for (Connector connector: connectors) {
                try {
                    connector.pause();
                } catch (Exception e) {
                    log.error(sm.getString(
                            "standardService.connector.pauseFailed",
                            connector), e);
                }
                /** 关闭服务Socket **/
                connector.getProtocolHandler().closeServerSocketGraceful();
            }
        }
    
        if(log.isInfoEnabled())
            log.info(sm.getString("standardService.stop.name", this.name));
            
        /** 更正当前组件状态为STOPPING  **/
        setState(LifecycleState.STOPPING);
    
        /** 关闭engine 子组件 **/
        if (engine != null) {
            synchronized (engine) {
                engine.stop();
            }
        }
    
        /** 关闭所有状态为STARTED Connector子组件 **/
        synchronized (connectorsLock) {
            for (Connector connector: connectors) {
                if (!LifecycleState.STARTED.equals(
                        connector.getState())) {
                    // Connectors only need stopping if they are currently
                    // started. They may have failed to start or may have been
                    // stopped (e.g. via a JMX call)
                    continue;
                }
                try {
                    connector.stop();
                } catch (Exception e) {
                    log.error(sm.getString(
                            "standardService.connector.stopFailed",
                            connector), e);
                }
            }
        }
    
        /** 关闭mapperListener 子组件 **/
        if (mapperListener.getState() != LifecycleState.INITIALIZED) {
            mapperListener.stop();
        }
    
        /** 关闭所有Executor 子组件 **/
        synchronized (executors) {
            for (Executor executor: executors) {
                executor.stop();
            }
        }
    }
    
    3.5 销毁StandardService组件
    @Override
    protected void destroyInternal() throws LifecycleException {
        /** 销毁 mapperListener **/
        mapperListener.destroy();
    
        /** 销毁所有Connector 子组件 **/
        synchronized (connectorsLock) {
            for (Connector connector : connectors) {
                try {
                    connector.destroy();
                } catch (Exception e) {
                    log.error(sm.getString(
                            "standardService.connector.destroyFailed", connector), e);
                }
            }
        }
    
        /** 销毁所有Executor 子组件 **/
        for (Executor executor : findExecutors()) {
            executor.destroy();
        }
    
        /** 销毁engine 子组件 **/
        if (engine != null) {
            engine.destroy();
        }
    
        super.destroyInternal();
    }
    

    4 管理线程池组件

        /**
         * 返回Service组件中所有线程池组件
         */
        @Override
        public Executor[] findExecutors() {
            synchronized (executors) {
                Executor[] arr = new Executor[executors.size()];
                executors.toArray(arr);
                return arr;
            }
        }
    
    
        /**
         * 通过名称获取Service中指定线程池组件
         */
        @Override
        public Executor getExecutor(String executorName) {
            synchronized (executors) {
                for (Executor executor: executors) {
                    if (executorName.equals(executor.getName()))
                        return executor;
                }
            }
            return null;
        }
    
    
        /**
         * 删除Service线程池中只当线程池组件
         */
        @Override
        public void removeExecutor(Executor ex) {
            synchronized (executors) {
                if ( executors.remove(ex) && getState().isAvailable() ) {
                    try {
                        ex.stop();
                    } catch (LifecycleException e) {
                        log.error("Executor.stop", e);
                    }
                }
            }
        }
    

    5 管理Connector组件

        /**
         * 返回所有 Connector子组件
         */
        @Override
        public Connector[] findConnectors() {
            return connectors;
        }
    
    
        /**
         * 从Service组件中删除Connector子组件
         */
        @Override
        public void removeConnector(Connector connector) {
    
            synchronized (connectorsLock) {
                /** 从Connector子组件数组找到删除,connector子组件 **/
                int j = -1;
                for (int i = 0; i < connectors.length; i++) {
                    if (connector == connectors[i]) {
                        j = i;
                        break;
                    }
                }
                /** 没有找到忽略此动作 **/
                if (j < 0)
                    return;
    
                /** 对删除connector组件 停止动作**/
                if (connectors[j].getState().isAvailable()) {
                    try {
                        connectors[j].stop();
                    } catch (LifecycleException e) {
                        log.error(sm.getString(
                                "standardService.connector.stopFailed",
                                connectors[j]), e);
                    }
                }
                /** 将connector中Service设置为null **/
                connector.setService(null);
    
                /** 对connector数组中在删除connector子组件后connector子组件在数组中前移 **/
                int k = 0;
                Connector results[] = new Connector[connectors.length - 1];
                for (int i = 0; i < connectors.length; i++) {
                    if (i != j)
                        results[k++] = connectors[i];
                }
                connectors = results;
    
                /** support通知 connector属性变更 **/
                support.firePropertyChange("connector", connector, null);
            }
        }
    
    
        /**
         * 返回所有Connector在JMX 中ObjectName
         */
        public ObjectName[] getConnectorNames() {
            ObjectName results[] = new ObjectName[connectors.length];
            for (int i=0; i<results.length; i++) {
                results[i] = connectors[i].getObjectName();
            }
            return results;
        }
    

    6 管理Engine组件

    @Override
        public Engine getContainer() {
            return engine;
        }
    

    6 管理Mapper组件

        @Override
        public Mapper getMapper() {
            return mapper;
        }
    

    7 管理parentClassLoader

    /**
         * 获取父类加载器,这里parentClassLoader默认为null
         * 返回外部组件server.getParentClassLoader()默认是Shared类加载器
         */
        @Override
        public ClassLoader getParentClassLoader() {
            if (parentClassLoader != null)
                return parentClassLoader;
            if (server != null) {
                return server.getParentClassLoader();
            }
            return ClassLoader.getSystemClassLoader();
        }
    
    
        /**
         * 设置父类加载器
         */
        @Override
        public void setParentClassLoader(ClassLoader parent) {
            ClassLoader oldParentClassLoader = this.parentClassLoader;
            this.parentClassLoader = parent;
            support.firePropertyChange("parentClassLoader", oldParentClassLoader,
                                       this.parentClassLoader);
        }
    

    相关文章

      网友评论

          本文标题:Tomcat源码解析-组件之StandardService

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