tomcat学习随笔

Tomcat结构与原理

  • 一、组成
    • Server
      • Service
        • Connector
          • ProtocolHandler
            • Endpoint
            • Processor
          • Adaptor
        • Container
          • Engine
          • Host
          • Context
          • Wrapper
  • 运行
  • 热部署
    • jsp
    • war

tomcat根路径

tomcat根路径目录结构示意图

一、组成

tomcat结构示意图

tomcat结构debug示意图

Server

tomcat的实例,支持多个Service

Service

web服务,主要包含Connector(多个)和Container(一个)

Connector

连接器(支持多个)作用是协议(如http)通信,负责监听端口来接收消息请求,并传递给Container进行业务处理,再将结果响应会客户端。
过程:网络通信- 应用层协议解析-Request/Response与ServeletRequest/ServeletResponse转化

属性含义
protocol监听的协议,默认是HTTP/1.1(7.0:org.apache.coyote.http11.Http11Protocol,8.0:org.apache.coyote.http11.Http11NioProtocol)
port监听的端口号
minThread服务器启动时创建的处理请求的线程数
maxThread最大可以创建的处理请求的线程数
enableLookups为true表示可以通过调用request.getRemoteHost()进行DNS查询来得到远程客户端的实际主机名;否则不进行DNS查询,而是返回其ip地址
acceptCount当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理
connectionTimeout超时的时间数(以毫秒为单位)
redirectPort当前Connector不支持SSL,收到了一个SSL传输请求时重定向的端口号
SSLEnabled是否开启 sll 验证,在Https 访问时需要开启
URIEncodingURL字符编码

更多见源码:org.apache.catalina.connector.Connector

ProtocolHandler

协议处理器,将不同协议和通信方式组合封装。本身就是顶层接口。
举例过程:org.apache.coyote.http11.Http11NioProtocol --> org.apache.tomcat.util.net.AbstractEndpoint(start --> startAcceptorThreads) --> org.apache.coyote.AbstractProtocol

Endpoint

端点,负责socket的接收和发送。顶层抽象类是org.apache.tomcat.util.net.AbstractEndpoint。

Acceptor
AbstractEndpoint子类的内部类,继承AbstractEndpoint的抽象内部类Acceptor,具体逻辑实现不同。
作用就是用于监听 Socket 连接请求。

Handler
AbstractEndpoint子类的内部类,继承AbstractEndpoint的内部接口Handler,供具体ProtocolHandler的内部类包装。
作用就是与Processor交互。

SocketProcessor
AbstractEndpoint子类的内部类,实现Runnable,具体逻辑实现不同。
作用就是通过run方法执行handler与Processor交互。

Processor

处理器,负责构建(填充数据)Request和Response对象

Adaptor

适配器,负责Request/Response与ServeletRequest/ServeletResponse转化。
如org.apache.catalina.connector.CoyoteAdapter

Container

一个Service中仅有一个,负责业务处理。包含Engine、Host、Context、Wrapper
container子类结构

tomcat container子类结构示意图
Engine

引擎,用于处理连接的执行器。一个Service只能配置一个Engine

属性含义
name名称
defaultHost默认的Host虚拟机域名,如localhost

更多见源码:org.apache.catalina.core.StandardEngine

Host

虚拟机,基于域名匹配至指定虚拟机,类似于nginx 当中的server

属性含义
name域名,必须配置,如localhost,至少有一个Host的name与Engine的defaultHost一致
appBase应用的根路径,支持相对路径(相对于tomcat安装目录根目录),默认webapps
unpackWARs是否自动解压war,默认true
autoDeploy是否热部署war:替换到整个Context环境(即包含session之类),默认true

更多见源码:org.apache.catalina.core.StandardHost

Context

应用上下文,隔离各个web应用,一个Context对应一个WebappClassLoader。一个Host下支持配置多个Context

属性含义
docBase应用物理路径,支持相对路径(相对于Host的appBase),默认不配置
path应用上下文路径,默认不配置
reloadable是否热加载class:替换掉WebappClassLoader。正式环境不用,默认false

更多见源码:org.apache.catalina.core.StandardContext

Wrapper
Pipeline结构
org.apache.catalina.core.ContainerBaseorg.apache.catalina.core.StandardPipeline源码过程
org.apache.tomcat.util.net.AprEndpoint.SocketProcessor#doRun
org.apache.coyote.AbstractProtocol.AbstractConnectionHandler#process
org.apache.coyote.http11.AbstractHttp11Processor#process
// this.adapter.service(this.request, this.response);org.apache.catalina.connector.CoyoteAdapter#service// this.connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);org.apache.catalina.core.StandardEngineValve#invoke// host.getPipeline().getFirst().invoke(request, response);org.apache.catalina.core.StandardContextValve#invoke// wrapper.getPipeline().getFirst().invoke(request, response);org.apache.catalina.core.StandardWrapperValve#invoke// filterChain.doFilter(request.getRequest(), response.getResponse());org.apache.catalina.core.ApplicationFilterChain#internalDoFilter// this.servlet.service(request, response);
简易流程
EngineValue --> HostValue --> ContextValue --> WrapperValue --> FilterChain --> Servelet

运行

org.apache.catalina.startup.Bootstrap#main

1、初始化
org.apache.catalina.startup.Bootstrap#load
org.apache.catalina.startup.Catalina#load

1.1、加载配置初始化
org.apache.tomcat.util.digester.Digester#parse
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl#scanDocument
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl#scanStartElement
com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser#emptyElement
org.apache.tomcat.util.digester.Digester#startElement
调用各种rule
org.apache.tomcat.util.digester.ObjectCreateRule#begin

realClassNameorg.apache.catalina.core.StandardServerorg.apache.catalina.core.StandardServiceorg.apache.catalina.core.StandardEngineorg.apache.catalina.core.StandardHost

org.apache.catalina.startup.ConnectorCreateRule#begin

org.apache.catalina.connector.Connector# HTTP/1.1。其他协(见org.apache.catalina.connector.Connector#setProtocol)类似org.apache.coyote.http11.Http11AprProtocolorg.apache.tomcat.util.net.AprEndpointorg.apache.coyote.http11.Http11AprProtocol.Http11ConnectionHandler(包装Processor

1.2、init方法初始化
org.apache.catalina.core.StandardServer#initInternal
org.apache.catalina.core.StandardService#initInternal
org.apache.catalina.core.StandardEngine#initInternal
org.apache.catalina.connector.Connector#initInternal
org.apache.catalina.mbeans.MBeanFactory#createStandardContext

创建org.apache.catalina.connector.CoyoteAdapter并设置到org.apache.coyote.ProtocolHandler(如org.apache.coyote.http11.Http11AprProtocol|--> org.apache.coyote.AbstractProtocol#init|--> org.apache.tomcat.util.net.AbstractEndpoint#init|--> org.apache.tomcat.util.net.AbstractEndpoint#bind(有具体实现类实现,目的就是创建如socket的通信)

2、启动
org.apache.catalina.startup.Bootstrap#start
org.apache.catalina.startup.Catalina#start
org.apache.catalina.core.StandardServer#startInternal
org.apache.catalina.core.StandardService#startInternal
org.apache.catalina.core.StandardEngine#startInternal
org.apache.catalina.connector.Connector#startInternal

|--> org.apache.coyote.AbstractProtocol#start|--> org.apache.tomcat.util.net.AbstractEndpoint#start|--> 相应的Endpoint实现类的内部Poller类#init + start

tomcat类加载器
三个类加载器

tomcat类加载器debug示意图

破坏双亲委派

tomcat破坏双亲委派debug示意图

热部署

jsp

替换JasperLoader,重新加载类

org.apache.jasper.servlet.JspServletWrapper#service
// this.ctxt.compile();// 判断是否做修改,修改则重新生成java和class文件,并设置jspLoader加载器为null,reload标志为trueorg.apache.jasper.JspCompilationContext#compile// this.jspLoader = null;// this.jspCompiler.compile();// this.jsw.setReload(true);org.apache.jasper.compiler.Compiler#compileorg.apache.jasper.compiler.JDTCompiler#generateClass
// servlet = this.getServlet();// 如果reload为true,则销毁旧servelet对象(是否卸载相关类取决于GC能够回收)、生成新的对象以及初始化org.apache.jasper.servlet.JspServletWrapper#getServlet// this.destroy();// servlet = (Servlet)instanceManager.newInstance(this.ctxt.getFQCN(), this.ctxt.getJspLoader());// servlet.init(this.config);

替换org.apache.catalina.loader.WebappClassLoader,重新加载类
热加载class

org.apache.catalina.core.ContainerBase#backgroundProcess
// loader.backgroundProcess();org.apache.catalina.loader.WebappLoader#backgroundProcess// this.reloadable && this.modified() 为true就就行reload,其中this.modified() 是遍历了当前应用所有资源是否更改org.apache.catalina.core.StandardContext#reload// this.stop();// this.start();

war

重新初始化Context上下文环境,就是重新启动一个应用(断点过程一直无法执行到)。
代码调试过程,修改war展开后的应用根目录,虽然会被监听到,但因为是目录跳过了后续流程(没有reload、deployed或host存在该应用名称的缓存),相当于不处理(除非删除应用根目录之后再添加) 对war包更新、新增 和 应用移除(war包展开目录)有效
热部署war

org.apache.catalina.core.ContainerBase.ContainerBackgroundProcessor#processChildrenorg.apache.catalina.core.StandardContext#backgroundProcessorg.apache.catalina.core.ContainerBase#backgroundProcessorg.apache.catalina.util.LifecycleSupport#fireLifecycleEvent// 通过listener来通知org.apache.catalina.startup.HostConfig#lifecycleEvent// this.check();// 判断资源是否更改,更改则同样执行org.apache.catalina.core.StandardContext#reloadorg.apache.catalina.startup.HostConfig#checkResources// 条件符合情况下,重新初始化contextorg.apache.catalina.startup.HostConfig#deployApps()org.apache.catalina.startup.HostConfig#deployDescriptor

参考 tomcat9调优3:Tomcat类加载机制及其热部署热加载原理剖析

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

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

相关文章

Python(八)字符编码

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

【youcans动手学模型】目标检测之 OverFeat 模型

欢迎关注『youcans动手学模型』系列 本专栏内容和资源同步到 GitHub/youcans 【youcans动手学模型】目标检测之 OverFeat 模型 1. OverFeat 卷积神经网络模型1.1 论文摘要1.2 技术背景1.3 基本方法模型设计多尺度分类滑动窗口(Sliding window)定位&#…

RabbitMQ高阶使用

1. 问题 2. 延时任务 2.1 什么是延时任务 在当前时间往后延迟多少时间执行的任务 2.1.1 和定时任务区别 定时任务有明确的触发时间,延时任务没有定时任务有执行周期,而延时任务在某事件触发后一段时间内执行,没有执行周期定时任务一般执行的…

二、RocketMQ消息存储源码分析

RocketMQ源码深入剖析 6 Broker源码分析 Broker模块涉及到的内容非常多,本课程重点讲解以下技术点: 1、Broker启动流程分析 2、消息存储设计 3、消息写入流程 4、亮点分析:NRS与NRC的功能号设计 5、亮点分析:同步双写数倍性…

洛谷P1059 [NOIP2006 普及组] 明明的随机数

(一)Question 1. 问题描述 2. Input 输入有两行,第 1 行为 1 个正整数,表示所生成的随机数的个数 N。第 2 行有 N 个用空格隔开的正整数,为所产生的随机数。 3. Output 输出也是两行,第 1 行为 1 个正整数 M,表示不相同的随机数的个数。第 2 行为 M 个用空格隔开的正…

“简单易懂的排序:深入了解直接选择排序“

文章目录 🔍 选择排序的原理与过程📈 选择排序的优缺点👉 代码实现 🔍 选择排序的原理与过程 本文我们直接说一个优化过的直接选择排序。其思路大同小异. 选择排序的思路很简单 每次从待排序的数据中选择一个最小和最大的元素&a…

fatal: unable to access ‘http://xxxx‘: Empty reply from server

当你遇到 “fatal: unable to access ‘http://xxxx’: Empty reply from server” 的错误信息时,通常表示 Git 客户端无法连接到指定的服务器或仓库。 以下是一些可能导致该错误的原因以及一些排除故障的步骤: 错误的 URL:确保你提供的 URL…

pdf转图片操作方法是什么?分享两个简单的方法!

PDF转图片是一个常见的需求,无论是为了方便编辑、共享,还是为了其他用途,我们需要简单而有效的方法来实现这个目标。本文将介绍两种简单的PDF转图片方法:记灵在线工具和截图方法。 记灵在线工具是一个强大而易于使用的在线工具&a…

UNIX网络编程卷一 学习笔记 第二十三章 高级SCTP套接字编程

SCTP是一个面向消息的协议,递送给用户的是部分的或完整的消息。只有当发送大消息时,在对端才会递送部分的消息。部分消息被递送给应用后,多个部分消息组合成单个完整消息不由SCTP负责。在SCTP应用进程看来,一个消息既可由单个输入…

Mars3d采用ellipsoid球实现模拟地球旋转效果

1.Mars3d采用ellipsoid球实现模拟地球旋转效果 2.开始自选装之后,模型一直闪烁 http://mars3d.cn/editor-vue.html?idgraphic/entity/ellipsoid 3.相关代码: import * as mars3d from "mars3d"export let map // mars3d.Map三维地图对象 …

WPS Office AI实战:智能表格化身智能助理

前面我们已经拿 WPS AI 对Word文字、PPT幻灯片、PDF 做了开箱体验,还没有看过的小伙伴,请翻看以前的文章,本文开始对【智能表格】进行AI开箱测验。 表格在日常的数据处理中占绝对地位,但表格处理并不是每一个人都擅长,…

第2讲 KMD ISP子系统缩略词及目录结构

QCOM Camera子系统缩略词介绍 CPAS(Camera Peripherals and Support)CDM(Camera Data Mover)TFE(Thin Front End)IFE(Image Front End)OPE(Offline Processing Engine)BPS(Bayer Processing Segment)SFE(Sensor Front End)LRME(Low Resolution Motion Estimation)CSID(Camera …