在了解了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。

How Tomcat works — 三、tomcat启动(2)的更多相关文章

  1. 攻城狮在路上(肆)How tomcat works(三) 连接器:Connector

     在介绍中提到,Catalina中有两个主要的模块:连接器和容器.本章中你将会写一个可以创建更好的请求和响应对象的连接器,用来改进第2章中的程序.一个符合Servlet 2.3和2.4规范的连接器必须 ...

  2. How Tomcat works — 四、tomcat启动(3)

    上一节说到StandardService负责启动其子组件:container和connector,不过注意,是有先后顺序的,先启动container,再启动connector,这一节先来看看conta ...

  3. tomcat 解析(三)-启动框架

    TOMCAT源码分析(启动框架)前言:   本文是我阅读了TOMCAT源码后的一些心得. 主要是讲解TOMCAT的系统框架, 以及启动流程.若有错漏之处,敬请批评指教!建议:   毕竟TOMCAT的框 ...

  4. How Tomcat Works(三)

    上文中描述的简单的服务器是不符合Servlet规范的,所以本文进一步描述一个简单的Servlet容器是怎么实现的 所以我们首先要明白Servlet接口规范,规范有不同版本,本人就先一视同仁了: pub ...

  5. How Tomcat works — 二、tomcat启动(1)

    主要介绍tomcat启动涉及到的一些接口和类. 目录 概述 tomcat包含的组件 server和service Lifecycle Container Connector 总结 概述 tomcat作 ...

  6. How Tomcat Works(十一)

    本文接下来分析tomcat的类载入器,tomcat需要实现一个自定义的载入器,而不能使用系统类载入器 (1)限制serlvet访问当前运行的java虚拟机中环境变量CLASSPATH指明的路径下的所有 ...

  7. How Tomcat Works(九)

    本文接下来描述servlet容器是怎样管理其相关组件的生命周期的,首先本人描述一下事件监听模式,也可以称为观察者模式,该模式分为以下角色 即抽象主题角色 具体主题角色 抽象观察者角色及具体观察者角色, ...

  8. how tomcat works 读书笔记四 tomcat的默认连接器

    事实上在第三章,就已经有了连接器的样子了,只是那仅仅是一个学习工具,在这一章我们会開始分析tomcat4里面的默认连接器. 连接器 Tomcat连接器必须满足下面几个要求 1 实现org.apache ...

  9. how tomcat works 总结

    希望各位网友在看完<<how tomcat works>>一书或者鄙人的tomcat专栏文章后再看这篇博客 这里主要是梳理各个章节的核心概念 第一章 一个简单的Web服务器 第 ...

随机推荐

  1. (转载)python 命名.py 不能与模块相同,否则会报错

    在学习python网页爬虫时,测试requests的post方法进行表单提交时,命名.py文件为requests.py 代码如下: import requests params={'firstname ...

  2. 解决mysql for docker容器报错:Authentication plugin 'caching_sha2_password' cannot be loaded

    为图方便,懒得在mac上安装mysql了,一个是管理不方便,第二个是为了方便多机器同步开发环境.就使用docker安装了. 拉取mysql镜像 docker pull mysql 运行mysql实例 ...

  3. 2019.03.11 COGS2652 秘术(天文密葬法)(分数规划+长链剖分)

    传送门 题意:nnn个点的树,每个点两个值a,ba,ba,b,问长度为mmm的路径∑ai∑bi\frac{\sum a_i}{\sum b_i}∑bi​∑ai​​的最大值. 思路:一眼要01分数规划, ...

  4. Web表现层

    目录 Web表现层调用过程... 2 延迟... 3 什么是延迟... 3 延迟的构成... 3 最基本的优化思路:... 4 Web表现层性能优化... 4 Web性能的基本指标... 4 Web性 ...

  5. 直播流RTMP 知识

    分享直播相关知识点: http://blog.csdn.net/kingroc/article/details/50839994 #!/bin/bash# Order Finish Startup# ...

  6. flask-钩子函数&g对象

    常用钩子函数 在Flask中钩子函数是使用特定的装饰器装饰的函数.钩子函数可以在正常执行的代码中,插入一段自己想要执行的代码.那么这种函数就叫做钩子函数.(hook) before_first_req ...

  7. 起步:Proteus 8 仿真 Arduino 1.8.2

    一.环境准备 1.从Arduino官网或中文社区下载并安装 Arduino IDE 当前最新版1.8.2:http://www.arduino.cn/thread-5838-1-1.html 2.下载 ...

  8. 程序员基层知识程序与cpu【更新1】

    我是一个小白,但我通过学习我慢慢的懂了一些事.分享出来有错误的望大咖指导. 我们要很明确的明白我们学的是编程而不是编程语言,编程语言只是工具用来方便我们做很多编程有关的事. 首先我在学习的过程中,第一 ...

  9. Requests+正则表达式抓取猫眼电影TOP100

    spider.py # -*- coding:utf-8 -*- import requests import re import json import codecs from requests.e ...

  10. 如何让 Git 使用 HTTP 代理服务器

    因为我们的内部网络使用了代理,所以在 安装 OpenStack 基于 Web 的管理控制台 的时候有个小麻烦,我们的 http 代理服务器无法通过 git 协议下载 openstack-dashboa ...