Tomcat初始化源码流程分析(图解及源码注释) (二)

 

Tomcat源码系列:


 

本章为Tomcat初始化流程的第二章,主要内容有Server的初始化,Engine的初始化以及Connector的初始化

Tomcat初始化源码不适用于新手

文章内容只有部分流程的源码分析,通过代码注释的方法,仅适用于Tomcat的源码有一定的了解的同学

目录

1.Service初始化 --->StandardService.initInternal()

1.1 Engine初始化 ---> StandardEngine.initInternal()

1.1.1 StartStopExecutor初始化 ---> StandardEngine父类ContainerBase.initInternal()

1.2 Connector初始化 ---> Connector.initInternal()

1.2.1 CoyoteAdpater适配器初始化

1.2.2 ProtocolHandler初始化 ---> AbstractProtocol.init()

1.2.3 Enpoint.bind() ---> Enpoint.init()调用NioEndpoint.bind()


初始化流程图如下:

1.Service初始化 --->StandardService.initInternal()

protected void initInternal() throws LifecycleException {

        //调用父类的initInternal
        super.initInternal();

        //engine是Tomcat的顶级容器
        if (engine != null) {
            engine.init();
        }

        //初始化线程池
        for (Executor executor : findExecutors()) {
            if (executor instanceof JmxEnabled) {
                ((JmxEnabled) executor).setDomain(getDomain());
            }
            //线程池会将子容器的初始化工作交给线程完成
            executor.init();
        }

        // 初始化映射监听
        mapperListener.init();

        // 初始化连接器
        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);
                }
            }
        }
    }

1.1 Engine初始化 ---> StandardEngine.initInternal()

protected void initInternal() throws LifecycleException {
        // Ensure that a Realm is present before any attempt is made to start
        // one. This will create the default NullRealm if necessary.
        getRealm();//权限管理控制
        super.initInternal(); //线程池的初始化
    }

1.1.1 StartStopExecutor初始化 ---> StandardEngine父类ContainerBase.initInternal()

protected void initInternal() throws LifecycleException {
        //engine实际的init方法
        BlockingQueue<Runnable> startStopQueue = new LinkedBlockingQueue<>();
        //将子容器开始或者停止的任务放入该线程池
        startStopExecutor = new ThreadPoolExecutor(
                getStartStopThreadsInternal(),
                getStartStopThreadsInternal(), 10, TimeUnit.SECONDS,
                startStopQueue,
                new StartStopThreadFactory(getName() + "-startStop-"));
        startStopExecutor.allowCoreThreadTimeOut(true);
        super.initInternal();
    }

1.2 Connector初始化 ---> Connector.initInternal()

1.2.1 CoyoteAdpater适配器初始化

protected void initInternal() throws LifecycleException {

        super.initInternal();

        // 初始化适配器
        // 适配器作用:完成客服端请求到容器的映射 N个connector到一个container
        // 用于Coyote的Request,Response和HttpServlet的Request和Response适配
        adapter = new CoyoteAdapter(this);
        //用于统领EndPoint以及Processor
        //EndPoint负责Socket监听任务
        //Processor负责处理请求

        //设置适配器适配请求(由Coyote的Request以及Response转换为HttpServlet的Request以及Response)
        protocolHandler.setAdapter(adapter);

        // Make sure parseBodyMethodsSet has a default
        if (null == parseBodyMethodsSet) {
            setParseBodyMethods(getParseBodyMethods());
        }

        if (protocolHandler.isAprRequired() && !AprLifecycleListener.isInstanceCreated()) {
            throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprListener",
                    getProtocolHandlerClassName()));
        }
        if (protocolHandler.isAprRequired() && !AprLifecycleListener.isAprAvailable()) {
            throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprLibrary",
                    getProtocolHandlerClassName()));
        }
        if (AprLifecycleListener.isAprAvailable() && AprLifecycleListener.getUseOpenSSL() &&
                protocolHandler instanceof AbstractHttp11JsseProtocol) {
            AbstractHttp11JsseProtocol<?> jsseProtocolHandler =
                    (AbstractHttp11JsseProtocol<?>) protocolHandler;
            if (jsseProtocolHandler.isSSLEnabled() &&
                    jsseProtocolHandler.getSslImplementationName() == null) {
                // OpenSSL is compatible with the JSSE configuration, so use it if APR is available
                jsseProtocolHandler.setSslImplementationName(OpenSSLImplementation.class.getName());
            }
        }

        try {
            //调度AbstractProtocol的init方法
            //在此之间初始化Endpoint
            protocolHandler.init();
        } catch (Exception e) {
            throw new LifecycleException(
                    sm.getString("coyoteConnector.protocolHandlerInitializationFailed"), e);
        }
    }

1.2.2 ProtocolHandler初始化 ---> AbstractProtocol.init()

public void init() throws Exception {
        if (getLog().isInfoEnabled()) {
            getLog().info(sm.getString("abstractProtocolHandler.init", getName()));
        }
        //完成jmx
        if (oname == null) {
            // Component not pre-registered so register it
            oname = createObjectName();
            if (oname != null) {
                Registry.getRegistry(null, null).registerComponent(this, oname, null);
            }
        }

        if (this.domain != null) {
            rgOname = new ObjectName(domain + ":type=GlobalRequestProcessor,name=" + getName());
            Registry.getRegistry(null, null).registerComponent(
                    getHandler().getGlobal(), rgOname, null);
        }

        String endpointName = getName();
        endpoint.setName(endpointName.substring(1, endpointName.length()-1));
        endpoint.setDomain(domain);
        //初始化EndPoint
        endpoint.init();
    }

1.2.3 Enpoint.bind() ---> Enpoint.init()调用NioEndpoint.bind()

public void bind() throws Exception {

        //实例化ServerSocketChannel,并绑定端口和地址
        if (!getUseInheritedChannel()) {
            serverSock = ServerSocketChannel.open();
            socketProperties.setProperties(serverSock.socket());
            InetSocketAddress addr = (getAddress()!=null?new InetSocketAddress(getAddress(),getPort()):new InetSocketAddress(getPort()));
            //设置最大连接数量
            serverSock.socket().bind(addr,getAcceptCount());
        } else {
            // Retrieve the channel provided by the OS
            Channel ic = System.inheritedChannel();
            if (ic instanceof ServerSocketChannel) {
                serverSock = (ServerSocketChannel) ic;
            }
            if (serverSock == null) {
                throw new IllegalArgumentException(sm.getString("endpoint.init.bind.inherited"));
            }
        }
        serverSock.configureBlocking(true); //mimic APR behavior

        // 初始化accepter以及poller的数量
        if (acceptorThreadCount == 0) {
            // FIXME: Doesn't seem to work that well with multiple accept threads
            acceptorThreadCount = 1;
        }
        if (pollerThreadCount <= 0) {
            //minimum one poller thread
            pollerThreadCount = 1;
        }
        setStopLatch(new CountDownLatch(pollerThreadCount));

        // 有必要初始化ssl
        initialiseSsl();
        // 开启selector
        selectorPool.open();
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值