【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 不能调用init
    if (!state.equals(LifecycleState.NEW)) {
        invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
    }

    try {
        // 初始化之前 状态变更为init
        setStateInternal(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
 // Nio2Endpoint
 bind();


// 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) {
    // 启动所有的 service
    service.start();
}


synchronized (engine) {
      // 启动 Engine 子容器
      engine.start();
}

// 可以看到这里通过线程池进行异步处理
for (Container child : children) {
    // 这就是 Engine init 过程中构建好的线程池
    // 这个线程池是在实例化 Engine 时给 Host 用的
    // 处理逻辑在 StandardHost 中的 startInternal
    results.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 来处理。具体的流程在流程图中。
在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

时序预测 | KAN+Transformer时间序列预测(Python)

预测效果 基本描述 KANTransformer时间序列预测 KAN作为这两年最新提出的机制&#xff0c;目前很少人用&#xff0c;很适合作为时间序列预测的创新点&#xff0c;可以结合常规的网络加上个优化方法做创新。适合功率预测&#xff0c;负荷预测&#xff0c;流量预测&#xff0c;浓…

MSPM0G3507——GPIO例程讲解1——input_capture

函数&#xff1a; 参数&#xff1a; 返回值&#xff1a; 主函数代码&#xff1a; #include "ti_msp_dl_config.h"extern volatile uint32_t interruptVectors[];int main(void) {SYSCFG_DL_init(); //把所有的LED灯和按键初始化了一…

css grid实现九宫格布局

常见的九宫格布局可以使用flex布局实现&#xff0c;但是flex布局有个致命的缺陷&#xff0c;比如3行3列的布局&#xff0c;当第不足3个元素的时候&#xff0c;元素依然是平局平铺的&#xff0c;这样就不满足九宫格的效果&#xff0c;这种情况&#xff0c;使用grid布局可以轻松搞…

对兼容各操作系统的Anki选择题模板的更新——提供更方便的笔记修改功能

2021年当我想做一个兼容各操作系统的Anki选择题模板的时候&#xff0c;到处搜索茧中网&#xff0c;根本找不到相关内容&#xff0c;直到偶然在github上看到Simon Lammer的Anki持久化模块&#xff0c;才算真正实现。现在再在茧中网上搜索兼容各种操作系统的Anki选择题模板&#…

【百问大模型01】GPT4o最新特性介绍

1、GPT4o 最大的特性是对话响应速度很快 端到端能力300ms&#xff1b;之前是语音转成文字&#xff0c;再来理解分析&#xff1b;现在是直接端到端。 1&#xff09;丰富的语音风格 2&#xff09;理解语音内外的内容 3&#xff09;发出非语音的声音 4&#xff09;自然而及时…

苹果mac电脑救星CleanMyMac让我的电脑重获新生!

&#x1f389; 发现电脑的救星&#xff01;CleanMyMac让我的电脑重获新生&#xff01; CleanMyMac绿色免费版下载如下&#xff1a;记得保存哈&#xff0c;以防失效&#xff1a; https://pan.quark.cn/s/9b08114cf404 CleanMyMac X2024全新版下载如下: https://wm.makeding.…

6/22 第四周 python操作word

学习到了word有四个段落&#xff0c;都可以通过python来操作。 并且课程的体系&#xff0c;只是一个启蒙&#xff0c;需要在公司的项目中熟悉&#xff0c;从而具备专项测试的能力。 后续每天的学习笔记也需要侧重于理解的部分。

阿里云发送验证码流程

目录 1. 阿里云短信服务简介 2. 阿里云验证码发送流程 2.1 申请阿里云短信服务 2.2 短信模板及阿里云秘钥 1.开发者可以在自己的应用程序中集成短信发送功能。绑定发起测试的手机号&#xff0c;需要绑定的手机号才能成功发送验证码&#xff0c;其他的用户手机号发送的验…

2.APP测试-安卓adb抓取日志

1.打开手机的开发者模式&#xff0c;打开USB调试 &#xff08;1&#xff09;小米手机打开开发者模式&#xff1a; 【设置】-【我的设备】-【全部参数信息】-快速多次点击【OS版本】-进入开发者模式 &#xff08;2&#xff09;连接手机和电脑&#xff0c;手机打开USB调试 【设置…

智能虚拟集群系统在酒店楼宇中的应用

随着城市化建设的不断发展&#xff0c;酒店楼宇等建筑规模不断扩大、地面/地下楼层不断增加。面对日益复杂的通信环境&#xff0c;酒店服务和管理人员对无线通信系统的稳定性、覆盖范围、话音清晰度、应急响应能力等方面均提出了更高的需求。 需求痛点 面对繁忙的工作&#x…

Adobe Illustrator 矢量绘图软件下载,Ai 2024最新版获取!

Adobe Illustrator&#xff0c;无论是艺术品、图标还是海报等设计作品&#xff0c;Adobe Illustrator都能以超凡的表现力展现出设计师们的创意与才华。 近年来&#xff0c;随着人工智能技术的迅猛发展&#xff0c;各行各业都纷纷将这一技术引入自身领域&#xff0c;以提升工作效…

【洛谷P3366】【模板】最小生成树 解题报告

洛谷P3366 -【模板】最小生成树 题目描述 如题&#xff0c;给出一个无向图&#xff0c;求出最小生成树&#xff0c;如果该图不连通&#xff0c;则输出 orz。 输入格式 第一行包含两个整数 N , M N,M N,M&#xff0c;表示该图共有 N N N 个结点和 M M M 条无向边。 接下…

晶谷高温烧结导电浆料用低熔点玻璃粉 晶谷耐高温导电漆导电油墨高温玻璃粉

晶谷浆料玻璃粉是一种用于电子浆料的材料&#xff0c;它在电子浆料中起到粘结和降低烧结温度的作用&#xff0c;能够提高浆料与基材之间的结合力。 浆料玻璃粉的性能特点包括&#xff1a; - 软化点&#xff1a;软化点在350至650度之间。 - 热膨胀系数&#xff1a;热膨胀系数…

实现文件分片合并功能并使用Github Actions自动编译Release

一、编译IOS镜像 1.1 编译 起因是公司电脑使用的Win11 23H2的预览版&#xff0c;这个预览版系统的生命周期只到2024-09-18&#xff0c;到期后就会强制每两小时重启。这是Windows强制升级系统的一种手段。 虽然公司里的台式电脑目前用不到&#xff0c;但是里面还保留许多旧项…

上交商汤联合提出一种虚拟试穿的创新方法,利用自监督视觉变换器 (ViT) 和扩散模型

上交&商汤联合提出一种虚拟试穿的创新方法&#xff0c;利用自监督视觉变换器 (ViT) 和扩散模型&#xff0c;强调细节增强&#xff0c;通过将 ViT 生成的局部服装图像嵌入与其全局对应物进行对比。虚拟试穿体验中细节的真实感和精确度有了显着提高&#xff0c;大大超越了现有…

教大家封装一个基础el-table 行内气泡编辑框,你一定用的到

今天的任务就是封装这个用element ui 组件来封装&#xff0c;如果让你封装你会怎么封装呢&#xff1f; 不说废话了&#xff0c;直接上代码 新建一个EditablePopoverColumn.vue组件文件 <template><el-table-column :prop"prop" :label"label"&…

探索ChatTTS项目:高效的文字转语音解决方案

文章目录 &#x1f4d6; 介绍 &#x1f4d6;&#x1f4d2; ChatTTS &#x1f4d2;&#x1f4dd; 项目介绍&#x1f4dd; 项目亮点&#x1f4dd; UI &#x1f388; 项目地址 &#x1f388; &#x1f4d6; 介绍 &#x1f4d6; 在AI技术迅速发展的今天&#xff0c;文本到语音&…

Mac OS 如何在命令行下启动Docker

现象 当用 Mac air作为服务器时&#xff0c;远程登录上去后想使用 docker&#xff0c;却报如下错&#xff1a; Cannot connect to the Docker daemon at unix:///Users/aborn/.docker/run/docker.sock. Is the docker daemon running? 原因分析 因为 docker 有一个守护进程…

array_key_exists() expects parameter 2 to be array, null given

公众号获取微信服务器IP地址 错误代码如下 public function getwxIP(){//获取微信服务器IP地址$accessToken $this->getwxoaiAccessToken();$userToken new UserToken();$result $userToken->curl_get("https: //api.weixin.qq.com/cgi-bin/get_api_domain_ip…

根据状态转移写状态机-二段式

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 描述 题目描述&#xff1a; 如图所示为两种状态机中的一种&#xff0c;请根据状态转移图写出代码&#xff0c;状态转移线上的0/0等表示的意思是过程中data/flag的值。 要求&#xff1a; 1、 必须使用对应类型的状…