麒麟系统启动mysql 麒麟 启动tomcat_监听器

一、Tomcat请求流程

麒麟系统启动mysql 麒麟 启动tomcat_开发语言_02


组件是如何创建,初始化,销毁的呢,管理他们的生命周期是一个很关键的问题?如何实现一键启动?

答:tomcat的核心组件都抽象出公共的部分 lifecycle接口其中定义了:init()、start()、stop() 和 destroy()这么几个核心方法;在父组件中创建的时候需要调用子组件的init方法。所以只要调用顶层的 Service的init方法,整个tomcat就启动了。

麒麟系统启动mysql 麒麟 启动tomcat_监听器_03


这是lifecyle的模版方法

@Override
    public final synchronized void init() throws LifecycleException {
       // 1、判断状态
        if (!state.equals(LifecycleState.NEW)) {
            invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
        }

        try {
            // 2 触发 INITIALIZING 事件的监听器
            setStateInternal(LifecycleState.INITIALIZING, null, false);
           
            // 3 调用子类初始化方法
            initInternal();
            
            //  触发 INITIALIZED 事件的监听器 
            setStateInternal(LifecycleState.INITIALIZED, null, false);
        } catch (Throwable t) {
           
        }
    }

Tomcat 自定义了一些监听器,这些监听器是父组件在创建子组件的过程中注册到子组件的。比如 MemoryLeakTrackingListener 监听器,用来检测 Context 容器中的内存泄漏,这个监听器是 Host 容器在创建 Context 容器时注册到 Context 中的。我们还可以在 server.xml 中定义自己的监听器,Tomcat 在启动时会解析 server.xml,创建监听器并注册到容器组件。

整体类图:

麒麟系统启动mysql 麒麟 启动tomcat_麒麟系统启动mysql_04

二、 Tomcat启动流程

通常我通过执行tomcat bin下的 startup.sh 脚本启动tomcat,那么tomcat到底是如何启动的呢? 具体流程如下:

麒麟系统启动mysql 麒麟 启动tomcat_tomcat_05

2.1 Catalina 组件

它是个启动类,通过解析server.xml ,创建相应的组件,并调用server的start方法,向下传递启动。Catalina是一个管理则者的身份,它还需要处理各种异常场景,当发生 ctrl+ c 强制关闭时,是如何释放资源的。Catalina在JVM中注册了一个关闭的钩子。主要任务就是创建Server

public void start() {

        if (getServer() == null) {
            load();
        }

        if (getServer() == null) {
            log.fatal("Cannot start server. Server instance is not configured.");
            return;
        }

        long t1 = System.nanoTime();

        // Start the new server
        try {
            getServer().start();
        } catch (LifecycleException e) {
            
            return;
        }


        // Register shutdown hook
        if (useShutdownHook) {
            if (shutdownHook == null) {
                shutdownHook = new CatalinaShutdownHook();
            }
            // 注册一个jvm的回调函数;内部其实是进行资源的释放和清理
            Runtime.getRuntime().addShutdownHook(shutdownHook);
        }
		
    // 监听停止请求
        if (await) {
            await();
            stop();
        }
    }
2.2 Server 组件

Server的具体实现类是StandServer.这个组件会管理 service的生命周期。在server内部维护着多个service组件。还有一个重要的任务就是,启动Socket来监听停止端口。

// 启动 Service 组件
 if (getState().isAvailable()) {
  try {
 service.start();
 } catch (LifecycleException e) {
 // Ignore
 }
 }
2.3 Service 组件

Service组件的具体实现类是StandardService,

/**
     *
     * 这是service 实例
     *
     */
    private Server server = null;



    /**
     *
     * 连接器
     */
    protected Connector connectors[] = new Connector[0];
    private final Object connectorsLock = new Object();

    /**
     * engine容器
     *
     */
    private Engine engine = null;


@Override
    protected void startInternal() throws LifecycleException {

   
        // 1、触发启动监听器
        setState(LifecycleState.STARTING);

        //  2、启动引擎
        if (engine != null) {
            synchronized (engine) {
                engine.start();
            }
        }


        // 3、mapper监听器 热加载部署
        mapperListener.start();

        
        // 4、连接器的启动 内部会启动子组建 如:endoint组件
        synchronized (connectorsLock) {
            for (Connector connector: connectors) {
                        connector.start();
                }
            }
        }
    }

service作为管理者,最重要的是维护其他组件的生命周期;启动组件时要维护依赖关系。

2.4 Engine组件

engine组件的本质是一个容器,它继承了ContainerBase基类,并实现了Engine接口

public class StandardEngine extends ContainerBase implements Engine {
 }

参考

极客时间-深入理解Tomcat