【tomcat】tomcat系统架构以及核心启动流程

对于web后端开发工程师来说,tomcat作为一个应用服务器框架本质上就是一个HTTP服务+Servlet容器。研究过spring、spring mvc源码的同学应该了解,spring mvc其实就是基于Servlet规范实现的请求的转发路由、转发处理。而Spring和SpringMVC就是通过web.xml文件中的事件监听器ContextListener加载Spring容器,然后在加载SpringMVC子容器。

所以带着几个问题,去学习tomcat的原理,本篇先聊聊基础架构,以及核心的启动流程。

  • 基本架构如何,以及各个组件如何功能
  • 启动的核心流程
  • 处理请求的核心流程
  • tomcat的是如何打破双亲委派模型,进行的类加载
  • tomcat的线程模型
  • tomcat的性能调优

在这里插入图片描述

tomcat系统架构

在这里插入图片描述
对于tomcat来说,比较重要的就是server.xml文件

1 <Server> //顶层组件,可以包括多个Service
2 <Service> //顶层组件,可包含一个Engine,多个连接器
3 <Connector/> //连接器组件,代表通信接口
4 <Engine> //容器组件,一个Engine组件处理Service中的所有请求,包含多个Host
5 <Host> //容器组件,处理特定的Host下客户请求,可包含多个Context
6 <Context/> //容器组件,为特定的Web应用处理所有的客户请求
7 </Host>
8 </Engine>
9 </Service>
10 </Server>

在这里插入图片描述
Connector 连接器:对外交流
Container 容器:内部处理
Server:负责和管理启动多个service,加痛8005端口的shutdown命令。关闭整个容器

启动流程

启动类就是BootStrap的main方法。

init

在这里插入图片描述
初始化反射生成一个Catalina对象。这里有类加载器的操作,先不介绍,后面在进行单独讲解。

daemon.load(args);

在这里插入图片描述
反射调用catalina.load()方法

 digester.parse(inputSource); // 解析server.xml文件 构建对象
getServer().init(); // 初始化 可以看到这里是StandardServer

在这里插入图片描述

public final class StandardServer extends LifecycleMBeanBase implements Server 
// 因为StandardServer继承了LifeCycleMBeanBase 先调用父类的init()public final synchronized void init() throws LifecycleException {// 不是new 不能调用initif (!state.equals(LifecycleState.NEW)) {invalidTransition(Lifecycle.BEFORE_INIT_EVENT);}try {// 初始化之前 状态变更为initsetStateInternal(LifecycleState.INITIALIZING, null, false);// 模版方法 拓展使用initInternal();// 初始化完成setStateInternal(LifecycleState.INITIALIZED, null, false);} catch (Throwable t) {// 初始化异常 修改成 公共逻辑handleSubClassException(t, "lifecycleBase.initFail", toString());}
}for (Service service : services) {// Service组件初始化service.init();
}


这里只有一个对象,所以对StandardService进行初始化,在初始化Service的时候,发现需要先初始化engine

在这里插入图片描述
在这里插入图片描述

if (engine != null) {// 1.Engine组件, 即servlet容器 初始化// 创建了一个线程池用于后续start流程中的 Host 的启动engine.init();}// Initialize our defined Connectors
synchronized (connectorsLock) { // 加锁操作for (Connector connector : connectors) {// 2. Connector组件 初始化// endpoint 绑定端口connector.init();}
}// TODO 重点关注 Endpoint 的端口绑定与 NIO的监听
protocolHandler.init();// Endpoint 组件的初始化
endpoint.init();// 三种实现, 默认 NioEndpoint// BioEndpoint// NioEndpoint// Nio2Endpointbind();// NIO之 获取通道 SocketChannel
serverSock = ServerSocketChannel.open();socketProperties.setProperties(serverSock.socket());
InetSocketAddress addr = new InetSocketAddress(getAddress(), getPortWithOffset());// NIO之 绑定端口( IP:PORT )
serverSock.socket().bind(addr,getAcceptCount());

在这里插入图片描述

总结下,其实初始化的过程就是把一些基础的东西进行加载。主要是绑定8090端口。

start

在这里插入图片描述
这里执行start方法,会去反射调用catalina.start()方法

 // TODO 3.真正启动daemon.start();Method method = catalinaDaemon.getClass().getMethod("start", (Class [])null);method.invoke(catalinaDaemon, (Object [])null);// 执行启动
getServer().start();// 循环遍历service
for (Service service : services) {// 启动所有的 serviceservice.start();
}synchronized (engine) {// 启动 Engine 子容器engine.start();
}// 可以看到这里通过线程池进行异步处理
for (Container child : children) {// 这就是 Engine init 过程中构建好的线程池// 这个线程池是在实例化 Engine 时给 Host 用的// 处理逻辑在 StandardHost 中的 startInternalresults.add(startStopExecutor.submit(new StartChild(child)));
}open();// 启动 Connector 组件
connector.start();
protocolHandler.start();
endpoint.start();// 创建线程池
public void createExecutor() {internalExecutor = true;TaskQueue taskqueue = new TaskQueue();TaskThreadFactory tf = new TaskThreadFactory(getName() + "-exec-", daemon, getThreadPriority());executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);taskqueue.setParent( (ThreadPoolExecutor) executor);}// 等待
public void await() {getServer().await();
}

在这里插入图片描述

小结

其实就是三个流程,初始化、解析文件、启动。
而最终的处理请求由acceptor\poller\worker 来处理。具体的流程在流程图中。
在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/32396.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch过滤器(Filter):原理及使用

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属专栏&#xff1a;C语言 &#x1f680;本系列文章为个人学习…

【MATLAB源码-第227期】基于matlab的北方苍鹰优化算法(NGO)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 鼠群优化算法&#xff08;Rat Swarm Optimization, RSO&#xff09; 简介 鼠群优化算法&#xff08;Rat Swarm Optimization, RSO&#xff09;是一种模仿鼠类群体觅食行为的优化算法。该算法属于群体智能算法&#xff0c;通…

ElementPlus el-date-picker日期时间选择器组件禁用此刻之前的时间(精确时分秒)

需求&#xff1a;如上图所示&#xff0c;此刻之前的日期和时间都不可选&#xff0c;也就是选择当天的话需要限制时间选择器&#xff0c;如果选择的是今天之后的日期则不需要限制时间选择器。 实现思路 限制日期 使用DateTimePicker 日期时间选择器 的disabled-date 限制时间…

yolov8训练初体验

最近在爬一些数据&#xff0c;有些网址的验证码比较难搞&#xff0c;于是使用yolov8来解决。 一、数据打标签并转为txt 使用的软件为X-AnyLabeling。内置各种模型&#xff0c;方便打标。 打标完成后由于是json格式&#xff0c;所以我们使用python转换即可 import json import…

awdawdad

作者主页&#xff1a; 作者主页 本篇博客专栏&#xff1a;C 创作时间 &#xff1a;2024年6月20日 最后&#xff1a; 十分感谢你可以耐着性子把它读完和我可以坚持写到这里&#xff0c;送几句话&#xff0c;对你&#xff0c;也对我&#xff1a; 1.一个冷知识&#xff1a; …

阿赵UE引擎C++编程学习笔记——C++自定义蓝图函数

大家好&#xff0c;我是阿赵。   使用UE引擎&#xff0c;大部分功能都可以使用蓝图的自带节点去完成。但有时候我们也需要扩展一些蓝图没有的功能。这一篇主要学习一下怎样用C给蓝图新增自定义的函数节点。 一、 新建蓝图函数库 在添加C类的时候&#xff0c;选择蓝图函数库&…

指纹浏览器与虚拟机的区别及在跨境电商中的应用

在如今数字化世界中&#xff0c;隐私和安全变得愈发重要。许多人在网络上进行敏感操作&#xff0c;如网上购物、在线银行、社交媒体管理等。为了保护自己的隐私&#xff0c;人们常常会寻求一些额外的工具&#xff0c;比如指纹浏览器和虚拟机。这两种工具在保护个人隐私方面都有…

Thinkphp5内核流浪猫流浪狗宠物领养平台H5源码

Thinkphp5内核流浪猫流浪狗宠物领养平台H5源码 可封装APP&#xff0c;适合做猫狗宠物类的发信息发布&#xff0c;当然懂的修改一下&#xff0c;做其他信息发布也是可以的。 Thinkphp5内核流浪猫流浪狗宠物领养平台H5源码

Linux常用命令(14)—查看文件内容(有相关截图)

写在前面&#xff1a; 最近在学习Linux命令&#xff0c;记录一下学习Linux常用命令的过程&#xff0c;方便以后复习。仅供参考&#xff0c;若有不当的地方&#xff0c;恳请指正。如果对你有帮助&#xff0c;欢迎点赞&#xff0c;关注&#xff0c;收藏&#xff0c;评论&#xf…

JavaScript 冷知识大赏:带你领略不一样的编程乐趣

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 &#x1f4af;JavaScript 中的小 tips&#x1f4e7;1 严格模式&#x1f49e;…

Spring之IoC(容器配置、Spring坐标导入、获取bean)

这里的话&#xff0c;因为博主学习时间有限&#xff0c;并没有实际去操作&#xff0c;只是学习和了解一个大概的流程。 目录 一、引言 1、管理什么&#xff1f;&#xff08;对象&#xff1a;Service、Dao ...&#xff09; 2、如何将被管理的对象告知 IoC 容器?&#xff08;用…

【ARM 安全系列介绍 3.7 -- SM4 对称加密算】

请阅读【嵌入式开发学习必备专栏 Cache | MMU | AMBA BUS | CoreSight | Trace32 | CoreLink | GCC | CSH | Armv8/v9 系统异常分析】 文章目录 SM4 加密算法简介SM4 工作模式算法步骤加密举例注意事项 Principle of SM4 encryption algorithm SM4 加密算法简介 SM4是一种分组…

如何基于Redis实现分布式锁?

分布式锁介绍 对于单机多线程来说&#xff0c;在 Java 中&#xff0c;我们通常使用 ReetrantLock 类、synchronized 关键字这类 JDK 自带的 本地锁 来控制一个 JVM 进程内的多个线程对本地共享资源的访问。 下面是我对本地锁画的一张示意图。 本地锁 从图中可以看出&#xf…

Unity 限时免费资源 - FANTASTIC万圣节资源包

Unity 资源 - FANTASTIC - Halloween Pack 万圣节包 前言资源包内容领取兑换码 前言 亲爱的 Unity 游戏开发者们&#xff0c;今天要给大家介绍一款限时免费的优质资源包 - FANTASTIC - Halloween Pack 万圣节资源包。 这个资源包为您的游戏创作带来了丰富的万圣节主题元素。其…

开关阀(3):Fisher DVC6200定位器原理及调试

Fisher DVC6200---Digital Valve Controllers&#xff08; 数字阀门控制器&#xff09;简写 DVC,而6200是Fisher DVC定位器发展的一个系列型号&#xff0c;是Fisher结合DVC2000、DVC6000系列&#xff0c;取其特点发展的有着高适用性和高可靠性的阀门定位器。 DVC6200 原理&…

Apriori 处理ALLElectronics事务数据

通过Apriori算法挖掘以下事务集合的频繁项集&#xff1a; 流程图 代码 # 导入必要的库 from itertools import combinations# 定义Apriori算法函数 def apriori(transactions, min_support, min_confidence):# 遍历数据&#xff0c;统计每个项的支持度 item_support {}for tr…

AI数据分析:根据时间序列数据生成动态条形图

动态条形竞赛图&#xff08;Bar Chart Race&#xff09;是一种通过动画展示分类数据随时间变化的可视化工具。它通过动态条形图的形式&#xff0c;展示不同类别在不同时间点的数据排名和变化情况。这种图表非常适合用来展示时间序列数据的变化&#xff0c;能够直观地显示数据随…

亚马逊卖家注册业务类型怎么选?VC账号能申请?

在亚马逊卖家注册时&#xff0c;业务类型的选择是非常重要的&#xff0c;因为它将直接影响您的销售策略、费用结构以及您在平台上的权限。目前&#xff0c;亚马逊主要的卖家业务类型包括专业卖家和个人卖家&#xff0c;而VC&#xff08;Vendor Central&#xff09;账号和VE&…

Camtasia2024中文版最新电脑录屏剪辑神器!

大家好&#xff0c;今天我要安利一个我最近超级喜欢的工具——Camtasia2024中文版&#xff01;这款软件真的太棒了&#xff0c;它让我的视频编辑工作变得更加轻松和高效。如果你也对视频制作感兴趣&#xff0c;那么一定要尝试一下这款神器哦&#xff01; Camtasia2024win-正式…

动态规划02(Leetcode62、63、343、96)

参考资料&#xff1a; https://programmercarl.com/0062.%E4%B8%8D%E5%90%8C%E8%B7%AF%E5%BE%84.html 62. 不同路径 题目描述&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移…