Tomcat源码分析(六) -- Srevice

245 阅读3分钟

Tomcat 中的Service

Service 定义

public interface Service extends Lifecycle {

    public Engine getContainer();

    public void setContainer(Engine engine);

    public String getName();

    public void setName(String name);

    public Server getServer();

    public void setServer(Server server);

    public ClassLoader getParentClassLoader();

    public void setParentClassLoader(ClassLoader parent);

    public String getDomain();

    public void addConnector(Connector connector);

    public Connector[] findConnectors();

    public void removeConnector(Connector connector);

    public void addExecutor(Executor ex);

    public Executor[] findExecutors();

    public Executor getExecutor(String name);

    public void removeExecutor(Executor ex);

    Mapper getMapper();
}
  • Service 继承了Lifecycle 接口,实现方法在 LifecycleBase 中
  • Service 中包含了一个容器 Engine
  • Service 中包含了一组 Connector
  • Service 的实现类是 StandardService

StandardService 的 initInternal 方法

protected void initInternal() throws LifecycleException {
    super.initInternal();

    if (engine != null) {
        //初始化引擎
        //注意 service 跟 engine 的关系是一对一
        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 {
                //初始化连接器
                //注意 service 跟 connector 的关系是一对多
                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);
            }
        }
    }
}
  • 这里现在只需要关心 engine 的 init 方法 和 所有 Connector 的 init 方法

StandardService 的 startInternal 方法

protected void startInternal() throws LifecycleException {
    //这里的逻辑跟 init 基本一样,就是把 init 转换为 start
    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);
            }
        }
    }
}

StandardService 的 stopInternal 方法

protected void stopInternal() throws LifecycleException {

    // Pause connectors first
    //注意这里是先暂停连接器
    synchronized (connectorsLock) {
        for (Connector connector: connectors) {
            try {
                connector.pause();
            } catch (Exception e) {
                log.error(sm.getString(
                    "standardService.connector.pauseFailed",
                    connector), e);
            }
            // Close server socket if bound on start
            // Note: test is in AbstractEndpoint
            connector.getProtocolHandler().closeServerSocketGraceful();
        }
    }

    if(log.isInfoEnabled())
        log.info(sm.getString("standardService.stop.name", this.name));
    setState(LifecycleState.STOPPING);

    // Stop our defined Container second
    if (engine != null) {
        synchronized (engine) {
            //关闭引擎
            engine.stop();
        }
    }

    // Now stop the connectors
    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);
            }
        }
    }

    // If the Server failed to start, the mapperListener won't have been
    // started
    if (mapperListener.getState() != LifecycleState.INITIALIZED) {
        mapperListener.stop();
    }

    synchronized (executors) {
        for (Executor executor: executors) {
            executor.stop();
        }
    }
}
  • 需要注意关闭的顺序

StandardService 的 destroyInternal 方法

protected void destroyInternal() throws LifecycleException {
    mapperListener.destroy();

    // Destroy our defined Connectors
    synchronized (connectorsLock) {
        for (Connector connector : connectors) {
            try {
                //销毁连接器
                connector.destroy();
            } catch (Exception e) {
                log.error(sm.getString(
                    "standardService.connector.destroyFailed", connector), e);
            }
        }
    }

    // Destroy any Executors
    for (Executor executor : findExecutors()) {
        executor.destroy();
    }

    if (engine != null) {
        //销毁引擎
        engine.destroy();
    }

    super.destroyInternal();
}

StandardService 的 setContainer 方法

public void setContainer(Engine engine) {
    //把旧引擎和当前 Service 对象解绑
    Engine oldEngine = this.engine;
    if (oldEngine != null) {
        oldEngine.setService(null);
    }
    //为新引擎绑定当前 Service 对象
    this.engine = engine;
    if (this.engine != null) {
        this.engine.setService(this);
    }
    //启动新引擎
    if (getState().isAvailable()) {
        if (this.engine != null) {
            try {
                this.engine.start();
            } catch (LifecycleException e) {
                log.error(sm.getString("standardService.engine.startFailed"), e);
            }
        }
        // Restart MapperListener to pick up new engine.
        try {
            mapperListener.stop();
        } catch (LifecycleException e) {
            log.error(sm.getString("standardService.mapperListener.stopFailed"), e);
        }
        try {
            mapperListener.start();
        } catch (LifecycleException e) {
            log.error(sm.getString("standardService.mapperListener.startFailed"), e);
        }
        //关闭就引擎
        if (oldEngine != null) {
            try {
                oldEngine.stop();
            } catch (LifecycleException e) {
                log.error(sm.getString("standardService.engine.stopFailed"), e);
            }
        }
    }

    // Report this property change to interested listeners
    support.firePropertyChange("container", oldEngine, this.engine);
}

StandardService 的 addConnector 方法

public void addConnector(Connector connector) {
    //加锁
    synchronized (connectorsLock) {
        //为新的连接器绑定当前 Service 对象
        connector.setService(this);
        //先扩容再添加
        Connector results[] = new Connector[connectors.length + 1];
        System.arraycopy(connectors, 0, results, 0, connectors.length);
        results[connectors.length] = connector;
        connectors = results;

        if (getState().isAvailable()) {
            try {
                //启动新的连接器
                connector.start();
            } catch (LifecycleException e) {
                log.error(sm.getString(
                    "standardService.connector.startFailed",
                    connector), e);
            }
        }
        // Report this property change to interested listeners
        support.firePropertyChange("connector", null, connector);
    }
}

StandardService 的 removeConnector 方法

public void removeConnector(Connector connector) {
    //加锁
    synchronized (connectorsLock) {
        //获取要移除的连接器
        int j = -1;
        for (int i = 0; i < connectors.length; i++) {
            if (connector == connectors[i]) {
                j = i;
                break;
            }
        }
        //没找到直接返回
        if (j < 0)
            return;
        //如果还是活动状态,关闭连接器
        if (connectors[j].getState().isAvailable()) {
            try {
                connectors[j].stop();
            } catch (LifecycleException e) {
                log.error(sm.getString(
                    "standardService.connector.stopFailed",
                    connectors[j]), e);
            }
        }
        //解绑 Service 对象
        connector.setService(null);
        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;
        // Report this property change to interested listeners
        support.firePropertyChange("connector", connector, null);
    }
}

小结

  • Service 内部最重要的是控制 Connector 数组和 Engine 对象
  • Connector 和 Engine 容器是一对多的关系
  • Service 中的 映射器和线程池后面再讲,如果忘得话,这里只关心 Connector 数组和 Engine 对象