美文网首页Tomcat
Tomcat启动分析(四) - Server、Service与E

Tomcat启动分析(四) - Server、Service与E

作者: buzzerrookie | 来源:发表于2018-09-13 19:27 被阅读4次

    在分析Lifecycle接口之后,本文分析Server与Service组件的初始化和启动过程。

    Server

    Server表示整个容器,Server接口的唯一实现类是StandardServer类,它继承了LifecycleMBeanBase类。它的initInternal方法很简单,初始化解析server.xml过程中添加的各Service。

    @Override
    protected void initInternal() throws LifecycleException {
        super.initInternal();
        // 省略与JMX有关的代码
        // Initialize our defined Services
        for (int i = 0; i < services.length; i++) {
            services[i].init();
        }
    }
    

    StandardServer类的startInternal方法也很简单,主要做了以下几件事:

    • 触发CONFIGURE_START_EVENT事件;
    • 启动命名服务(好像与JNDI有关,不太确定);
    • 启动解析server.xml过程中添加的各Service。
    @Override
    protected void startInternal() throws LifecycleException {
        fireLifecycleEvent(CONFIGURE_START_EVENT, null);
        setState(LifecycleState.STARTING);
    
        globalNamingResources.start();
    
        // Start our defined Services
        synchronized (servicesLock) {
            for (int i = 0; i < services.length; i++) {
                services[i].start();
            }
        }
    }
    

    Service

    Service处于Server和Engine之间,用来将Connector绑定到Engine上。Service接口的唯一实现类是StandardService类,它同样继承了LifecycleMBeanBase类。它的initInternal方法做了以下几件事:

    • 初始化解析server.xml过程中添加的Engine;
    • 初始化解析server.xml过程中添加的各Executor;
    • 初始化解析server.xml过程中添加的各Connector。
    @Override
    protected void initInternal() throws LifecycleException {
        super.initInternal();
        if (engine != null) {
            engine.init();
        }
        // Initialize any Executors
        for (Executor executor : findExecutors()) {
            if (executor instanceof JmxEnabled) {
                ((JmxEnabled) executor).setDomain(getDomain());
            }
            executor.init();
        }
        // Initialize mapper listener
        mapperListener.init();
        // Initialize our defined Connectors
        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);
                }
            }
        }
    }
    

    StandardService类的startInternal方法做了以下几件事:

    • 启动解析server.xml过程中添加的Engine;
    • 启动解析server.xml过程中添加的各Executor;
    • 启动解析server.xml过程中添加的各Connector。
    @Override
    protected void startInternal() throws LifecycleException {
        if(log.isInfoEnabled())
            log.info(sm.getString("standardService.start.name", this.name));
        setState(LifecycleState.STARTING);
    
        // Start our defined Container first
        if (engine != null) {
            synchronized (engine) {
                engine.start();
            }
        }
    
        synchronized (executors) {
            for (Executor executor: executors) {
                executor.start();
            }
        }
    
        mapperListener.start();
    
        // Start our defined Connectors second
        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);
                }
            }
        }
    }
    

    Executor

    Tomcat的Executor接口继承了Java的Executor接口,其唯一实现类是StandardThreadExecutor类,它同样继承了LifecycleMBeanBase类。它的initInternal方法很简单,没有做自己的事情。

    @Override
    protected void initInternal() throws LifecycleException {
        super.initInternal();
    }
    

    StandardThreadExecutor类的startInternal方法如下:

    @Override
    protected void startInternal() throws LifecycleException {
    
        taskqueue = new TaskQueue(maxQueueSize);
        TaskThreadFactory tf = new TaskThreadFactory(namePrefix,daemon,getThreadPriority());
        executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), maxIdleTime, TimeUnit.MILLISECONDS,taskqueue, tf);
        executor.setThreadRenewalDelay(threadRenewalDelay);
        if (prestartminSpareThreads) {
            executor.prestartAllCoreThreads();
        }
        taskqueue.setParent(executor);
    
        setState(LifecycleState.STARTING);
    }
    
    • TaskThreadFactory实现了ThreadFactory接口,新线程的名字是namePrefix加计数,namePrefix在XML中有对应属性可以设置;
    • 用上述线程工厂为自己创建了一个ThreadPoolExecutor。

    相关文章

      网友评论

        本文标题:Tomcat启动分析(四) - Server、Service与E

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