zoukankan      html  css  js  c++  java
  • How Tomcat works — 三、tomcat启动(2)

    在了解了tomcat 的一些基本组件之后,学习启动过程就更容易理解了,因为启动过程就是启动各个组件。

    目录

    • 启动顺序
    • Bootstrap类
    • Catalina类
    • StandardServer类和StandardService类
    • 总结

    启动顺序

    tomcat的启动主要是容器的启动,根据tomcat四层架构,启动时由上而下的,而service包含这些组件,service又包含在server里面,启动顺序如下:

    Bootstrap类

    整个tomcat程序的入口——main函数,主要作用就是找到CATALINA_HOME,实例化Catalina类,并调用load和start进行整个服务器的初始化和启动

    (上图中最后还有一个start调用,由于图太高了没有截)

    main函数中new出了Bootstrap实例,主要执行了以下方法

    • init:设置catalinaHome和catalinaBase(和catalinaHome一样)为bootstrap.jar的上一级目录,初始化tomcat的classLoader,获得Catalina的实例(后面load和start都调用了Catalina的方法)
    • setAwait:调用Catalina的setAwait设置服务器处于等待标志
    • load:调用Catalina的load方法进行服务器的初始化
    • start:调用Catalina的start方法启动服务器

    Catalina类

    主要作用是初始化并启动 StandardServer

    load

    load主要执行以下方法:

    • initDir:再次检查设置catalinaHome
    • initNaming:设置系统变量表明是否使用naming
    • createStartDigester:新建一个Digester解析server.xml,用来初始化StandardServer

    (最左边的是catalina)

    这里面最重要的就是createStartDigester方法(方法内部是添加一系列对应rule,要理解这个函数的实现要先去学习digest解析xml库),tomcat使用用来解析xml 的digest库,可以根据xml来生成对应的类并初始化:

    • digester.push(this):将catalina压在栈底(digester使用栈来解析xml),为了将StandardServer设置为catalina的变量(后面用到了StandardServer的init和start方法)
    • digester.parse():解析service.xml

    经过上面得到一个StandardServer的实例以后,调用StandardServer.init方法进行StandardServer的初始化。

    start

    start函数主要进行了以下操作:

    • 先判断getServer是否为null,若是则再次调用load进行初始化
    • 如果依然初始化失败则表明服务器初始化失败直接返回
    • getServer.start:调用StandardServer的start方法进行服务器初始化
    • 注册关闭服务器钩子(如果服务器没有正常关闭,该钩子可以进行关闭和清理工作)
    • 最后调用StandardServer的await方法监听端口等待关闭命令
    • 因为await方法是阻塞方法(等待socket),等await方法执行完成的时候(表明接收到shutdown命令)使用stop进行关闭服务器

    StandardServer类和StandardService类

    因为server和service联系紧密所以放到一块来说,server的主要任务是初始化并启动所有的service(如果有多个的话)

    StandardServer.init

    在catalina的load方法中调用了StandardServer的init方法,但是StandardServer没有重载超类LifeBase的init方法,所以是直接执行LifeBase.init方法

    最后会调用到StandardServer的initInternal方法,在该方法中进行了以下操作:

    • 调用父类LifecycleMBeanBase.initInternal方法进行注册MBean
    • 从低向上逐级验证tomcat类加载器
    • 使用循环逐个初始化service(在解析serverx.xml的时候已经实例化StandardService并调用StandardServer.addService()添加到StandardServer.services变量中),在标准server.xml配置中只有一个service——StandardService,所有就是只调用StandardService.init()

    StandardService.init

    最后也会调用到StandardService的initInternal方法,在该方法中进行了以下操作:

    • 调用父类LifecycleMBeanBase.initInternal方法进行注册MBeang
    • 如果container(这里的container是StandardEngine)不是null,则调用container的init方法进行初始化
    • 如果有Executor则逐个初始化
    • 最后使用循环逐个在初始化Connector,这里connector有两个,分别是用来处理两种协议:http和ajp

    StandardServer.start

    最后会调用StandardServe.startInternal,执行以下操作

    • 触发listener
    • 启动globalNamingResource
    • 启动所有service

    StandardService.start

    最后会调用到StandardService的startInternal,执行以下操作:

    • setState设置service的状态,并通知所有listener
    • 启动container
    • 启动executor
    • 启动connector(和初始化的时候一样)

    总结

    上一节说过StandardServer和StandardService的作用,但是经过这一节才更明白,service负责初始化并启动了container、executor和connector,所以接下来主要是分析StandardService如何启动container和connector。

  • 相关阅读:
    【反射】Java反射机制
    Composer教程之常用命令
    Composer教程之基础用法
    Composer教程之初识Composer
    Composer 的结构详解
    现代 PHP 新特性系列(七) —— 内置的 HTTP 服务器
    现代 PHP 新特性系列(一) —— 命名空间
    现代 PHP 新特性系列(二) —— 善用接口
    现代 PHP 新特性系列(三) —— Trait 概览
    现代 PHP 新特性系列(四) —— 生成器的创建和使用
  • 原文地址:https://www.cnblogs.com/sunshine-2015/p/5745868.html
Copyright © 2011-2022 走看看