知识小罐头08(tomcat8启动源码分析 上)
前面好几篇都说的是一个请求是怎么到servlet中的service方法的,这一篇我们来看看Tomcat8是怎么启动并且初始化其中的组件的?
相信看了前面几篇的小伙伴应该对Tomcat中的各个组件不陌生了,所以我们就可以加快一点速度;
简单说一下Tomcat启动流程,首先是设置一下各种类加载器,然后加载server.xml配置文件,然后初始化Container各个容器,最后就是连接器Connector。
1.批处理文件
双击startup.bat文件启动tomcat,其实内部就是跳转到catalina.bat文件(.bat文件时windows系统用的,那些.sh配置文件是Unix、Linux系统使用的)
startup.bat文件内部其实就是一些指令从上到下顺序执行,作用是进行一些目录的判断,并找到catalina.bat文件的位置,如下图所示
注意:.bat文件其实就是一个批处理文件,里面一条条的命令都有自己独特的语法,你知需要百度“startup.bat详解”可以看到很多博客,其实就我感觉很像mysql的触发器吧,里面封装了很多命令,有自己独特的语法,只要一触发就会一连串的执行,这里就不多说,不是我们的重点,用到的时候再去仔细研究,这里粗略提一下。
我们再看看catalina.bat文件
由于tomcat是用java语言开发出来的,所以启动Tomcat本质上就是运行一个java程序的main方法,然后后续就会初始化一系列的东西。
2.看看Bootstrap类的main方法
我们就看看main方法内核心部分,在下图中标识了三步:
总结一下,main方法内部核心就是创建一个Bootstrap对象,然后调用这个对象的init、load、start方法,看名字就应该大概猜出一点东西了:
init:大概是初始化一些类加载器什么的;
load:应该是加载什么配置文件,还记得我说过最重要的配置文件是哪个吗?对,就是server.xml文件,其实就是加载这个文件;
start:内部差不多初始化完了所有的容器和连接器,等待连接;
我们分别对这三个方法加断点进行调试,理解其中的原理之后整个Tomcat的启动流程也就清楚了!
3.init方法
还是只看核心的逻辑,至于怎么实例化类加载器和设置类加载器,感兴趣的小伙伴就自己去研究走走源码。
4.load方法
通过看源码,其实可以看到Bootstrap的load方法,就是通过反射调用Catalina的load方法
我们断点进入最后的那个invoke方法,看看Catalina的load方法是加载了些什么东西
这个Digester就是为了解析servler.xml定义了很多的解析规则,真要搞懂这个东西,肯定要花一定的时间去好好研究的;
我们在这里简单而随意看几个我们熟悉的东西,具体的解析过程肯定要自己去了解的;
这个Digester是了解servler.xml具体解析规则必要的东西,我们把规则已经指定好了,下一步肯定就是加载server.xml文件了
准备好了Digester和server.xml的流之后,然后底层用SAX去解析这个xml文件(注意,前面只是解析出来了server.xml中的各个组件对应的类名以及组件之间的父子关系, 没有实例化,到parse方法才真正实例化)
接着我们就要去把一些需要用到的容器进行一些初始化设置,更方便我们使用!
从这里开始我们就会看到一个类似多米诺骨牌效应的这么一个现象,一个接一个的初始化,而且这里涉及到了一个知识点叫做JMX,有关于这个JMX(Java Management Extensions),我查了很多的资料,网上复制粘贴的一大堆,看得很乱,虽然我没有怎么仔细的去研究,但是大概的逻辑我是知道了,下面就简单的说说;
5.JMX的简介和事件监听
便于理解,JMX可以想象成工商局,每家公司必须要向工商局注册自己,这个时候工商局就对每一家公司都有了管理的权利,无论是哪一家公司要改名字,要合并,注销等等,都必须经过工商局的的同意,工商局还能对一些非法公司进行整改什么的,可以说工商局就是管理了每一家公司的生命周期,可以对每家公司进行监控符合管理。
对应在Tomcat中,我们必须要把Tomcat中的所有组件(在这里叫做MBean,类似spring容器中叫做bean)给注册到一个叫做Registry的地方,Registry就是基于JMX搞出来的一个东西,然后我们执行所有组件的init,start方法,都可以在JMX中找到对应的MBean执行对应的init、start方法;这里也只是稍微提一下JMX,内容很多一下子说不完,最好自己多查查资料看看。
JMX的结构图找了好久,终于看到一个图比较满意的,进行一些小小的修改,如下所示:
Agent Layer(代理层):主要包括Agent Services中几个服务(计时器、监控、动态加载MBean、关系服务),还有MBean Server两部分组成
Distributed layer(分布层):包含一些比较厉害的组件,其实我感觉就类似可视化工具,可以很方便的对那些MBean进行一些管理和修改。
还有在MBean Server中的多个MBean组成一个Instrumentation Layer(指示层),这个就没啥说的;总之,JMX我用得不是很多,需要真正用到的时候再慢慢研究吧,哈哈!
感兴趣的小伙伴可以自己研究这个写几个HelloWorldMBean试试就ok了
再说说事件监听,事件监听又是一个什么鬼呢?不准确的来说,在Tomcat启动的时候会有个全局事件(就类似一个全局变量),很多的监听器会时时刻刻监听这个全局事件,当对一个组件进行一些操作(会修改状态码state),那么这个全局事件就会变化,遍历所有监听器执行某方法,下面就随便看看这个全局事件:
还记得最前面的server.xml配置文件的<server>中配置的很多监听器吗?其实就是配合这个全局事件起作用的(看英文应该翻译成生命周期事件吧。。。)
6.接第4步继续
这里一定要理清楚一个逻辑,Tomcat中所有组件都必须是LifecycleBase的子类(其实都直接或者间接的继承了LifecycleBase这个类),这个类就是所有组件的爸爸,假如这个爸爸有九个儿子,大儿子要给最小的儿子一颗糖,你就会看到一个很有趣很坑爹的现象:大儿子-------->爸爸---------->二儿子--------->爸爸--------->三儿子---------->爸爸---------->四儿子---------->.......------->爸爸------->最小的儿子!
这样糖才能到最小的儿子手里,是不是真的很坑爹,哈哈!
所以我们在Tomcat也可以看到一个这样的逻辑:
server.init()---------->LifecycleBase.init(), 在init()方法内部就会执行initInternal()方法,并改变全局事件------------->server中的initInternal()方法 ,内部执行service.init()方法------------>LifecycleBase.init(),执行initInternal()方法,并改变全局事件--------->service中的initInternal()方法,内部就是connector.init()和engine.init()---------->LifecycleBase.init()。。。。。后面都是这个逻辑,几乎一模一样,初始化之后启动start()的逻辑也是这个,所以这个逻辑一定要搞清楚,搞清楚这个了后面就没难度了。
下面我们就简单看看一些关键的地方,由于绝大部分都是相同的,就不一一截图了;
看看initInternal()方法内部:
一直往下看,我们看看StandardService中的initInternal()方法:
engine的初始化是在看不出来什么有趣的东西,我们就重点看看HTTP连接器的初始化的关键代码:
【省略很多重复步骤】
【省略很多重复步骤】
这个是Tomcat的NIO连接,其中addr=0.0.0.0/0.0.0.0:8080;acceptCount = 100;看这个就知道监听8080端口,默认并发连接数100个,这个可以自己根据实际情况设置
到这里Tomcat启动初始化的步骤算是结束了,内容看起来比较多,但是思路自我感觉还是比较清晰的,了解JMX和事件监听的相关知识之后,还是比较容易的,不过强调一点,一定要自己走走源码,加深理解!
这篇说的东西不多,就是初始化了几乎所有组件,就好像一个厨师,把所有的菜都洗好并且切好、分类、分盘,调料也准备就绪,下一步,就是开始做出美味的菜肴了。
下一篇我们简单看看Tomcat的start过程。
知识小罐头08(tomcat8启动源码分析 上)的更多相关文章
- 知识小罐头05(tomcat8请求源码分析 上)
这一篇我们不看源码,就大概理一下Tomcat内部组成部分!前面花费了两篇博客的篇幅来说说了一般的maven web项目并部署到tomcat运行,其实都是为这篇做铺垫的! 其实我下载了tomcat7,t ...
- 知识小罐头09(tomcat8启动源码分析 下)
初始化已经完成,现在就是启动这些组件,Tomcat中的start方法就是用于启动的,其实start的原理还是和上一篇说的初始化几乎一样!这里我就大概说一下,看几个比较关键的地方就行了. 前面的步骤就大 ...
- RocketMQ中Broker的启动源码分析(一)
在RocketMQ中,使用BrokerStartup作为启动类,相较于NameServer的启动,Broker作为RocketMQ的核心可复杂得多 [RocketMQ中NameServer的启动源码分 ...
- RocketMQ中Broker的启动源码分析(二)
接着上一篇博客 [RocketMQ中Broker的启动源码分析(一)] 在完成准备工作后,调用start方法: public static BrokerController start(Broker ...
- RocketMQ中PullConsumer的启动源码分析
通过DefaultMQPullConsumer作为默认实现,这里的启动过程和Producer很相似,但相比复杂一些 [RocketMQ中Producer的启动源码分析] DefaultMQPullCo ...
- Django如何启动源码分析
Django如何启动源码分析 启动 我们启动Django是通过python manage.py runsever的命令 解决 这句话就是执行manage.py文件,并在命令行发送一个runsever字 ...
- 知识小罐头07(tomcat8请求源码分析 下)
感觉最近想偷懒了,哎,强迫自己也要写点东西,偷懒可是会上瘾的,嘿嘿!一有写博客的想法要赶紧行动起来,养成良好的习惯. ok,继续上一篇所说的一些东西,上一篇说到Connector包装了那两个对象,最后 ...
- 【Netty之旅四】你一定看得懂的Netty客户端启动源码分析!
前言 前面小飞已经讲解了NIO和Netty服务端启动,这一讲是Client的启动过程. 源码系列的文章依旧还是遵循大白话+画图的风格来讲解,本文Netty源码及以后的文章版本都基于:4.1.22.Fi ...
- Quartz源码——scheduler.start()启动源码分析(二)
scheduler.start()是Quartz的启动方式!下面进行分析,方便自己查看! 我都是分析的jobStore 方式为jdbc的SimpleTrigger!RAM的方式类似分析方式! Quar ...
随机推荐
- BZOJ_3261_最大异或和_可持久化trie
BZOJ_3261_最大异或和_可持久化trie Description 给定一个非负整数序列{a},初始长度为N. 有M个操作,有以下两种操作类型: 1.Ax:添加操作,表示在序列末尾添加一个数x, ...
- 原生wcPop.js消息提示框(移动端)、内含仿微信弹窗效果
wcPop.js移动端消息对话框插件是之前的wxPop.js的升级版,优化了js和css,并且新增了仿微信弹窗效果, 是一款含有多种情景模式的原生模态消息对话框代码,可用于替代浏览器默认的alert弹 ...
- Maven的安装步骤
1.确保jdk安装成功,注意在系统环境下,必须添加jdk的路径.2.将maven的路径配置在系统环境变量中.3.修改maven的默认路径,即:将config下的settings.xml文件中的目录节点 ...
- Robot Framework源码解析(2) - 执行测试的入口点
我们再来看 src/robot/run.py 的工作原理.摘录部分代码: from robot.conf import RobotSettings from robot.model import Mo ...
- centos7开放端口和防火墙设置
centos7开放端口和防火墙设置. 查看防火墙状态: firewall-cmd --state 如果显示: not running 打开防火墙服务: systemctl start firewall ...
- python接口自动化(十八)--重定向(Location)(详解)
简介 在实际工作中,有些接口请求完以后会重定向到别的url,而你却需要重定向前的url.URL主要是针对虚拟空间而言,因为不是自己独立管理的服务器,所以无法正常进行常规的操作.但是自己又不希望通过主域 ...
- WinForm的DataGirdView判断CheckBox是否被选中
首先我们先设置下DataGirdView的列. 然后启动下编辑,就可以选中与不选中了.在之后通过. #region 便利被选中的行,然后导出 DataTable dtreport = new Data ...
- 如何定义开发完成?(Definition of Done)
最近在拜读郑晔的10x程序员工作法,收益良多,文中提出一个概念叫DoD(Definition of Done)给我的感触颇深.这让我联想到实际工作过程中,经常遇到的扯皮.争吵等各种场景,其实就和这个D ...
- HighChar 案例
Highchars //前台 <script> $(function () { //showChat(); initChat(); showPie(); initPie(); }) fun ...
- 【开发记录】如何在B/S项目中使用中国天气的实时天气功能
好久没有更新我的博客了,正好手头有一个比较合适的项目经验可以分享出来,就是这个如何使用中国天气的天气预报功能,也正好做个项目经验记录. 功能需求 这个功能需求比较简单,就是想在网页端显示实时天气数据. ...