1. tomcat入门

入门模块仅做学习大纲梳理,忽略了具体操作指引。

Tomcat的三种部署模式:

简单架构模型

连接器的非阻塞模式(NIO)

通道(Channel)、缓冲区(Buffer)、选择器(Selector)

容器container的责任链模式:

1.请求被Connector组件接收,创建Request和Response对象。

2.Connector将Request和Response交给Container,先通过Engine的pipeline组件流经内部的每个Valve。

3.请求流转到Host的pipeline组件中,并且经过内部Valve的过。

4.请求流转到Context的pipeline组件中,并且经过内部的Valve的过滤。

5.请求流转到Wrapper的pipeline组件中,并且经过内部的Valve的过滤。

6.Wrapper内部的WrapperValve创建FilterChain实例,调用指定的Servlet实例处理请求。

7.返回。

2.tomcat架构进阶

tomcat顶层结构

Server:服务器的意思,代表整个tomcat服务器,一个tomcat只有一个Server;

Service:Server中的一个逻辑功能层, 一个Server可以包含多个Service;

Connector:称作连接器,是Service的核心组件之一,一个Service可以有多个Connector,主要是连接客户端请求;

Container:Service的另一个核心组件,按照层级有Engine,Host,Context,Wrapper四种,一个Service只有一个Engine,其主要作用是执

行业务逻辑;
Jasper:JSP引擎;
Session:会话管理;

Connector解析

Connector使用ProtocolHandler来处理请求的Endpoint用来处理底层Socket的网络连接。

Processor用于将Endpoint接收到的Socket封装成Request。

Adapter充当适配器,用于将Request转换为ServletRequest交给Container进行具体的处理。

ProtocolHandler由包含了三个部件:Endpoint、Processor,Adapter

Container解析

service中的name是catalina,engine中的name也是catalina,这个就证明一个service就只有一个engine, 一个engine可以有多个host主机

host,站点,虚拟主机。

Engine:引擎、只有一个定义了一个名为Catalina的Engine

Host:站点、虚拟主机一个Engine包含多个Host的设计,使得一个服务器实例可以承担多个域名的服务,是很灵活的设计

Context:一个应用默认配置下webapps下的每个目录都是一个应用

Wrapper:一个Servlet

结合tomcat目录结构理解上面的4个容器之间的关系

3.tomcat类加载机制

引用自:https://www.cnblogs.com/ghoster/p/7602158.html

1.主流的Java Web服务器,如Tomcat、Jetty、WebLogic、WebSphere等都实现了自己定义的类加载器(一般都不止一个)。因为一个功能健全的web服务器要解决一下几个问题:

    1)部署在一个服务器上的两个web应用程序所使用的Java类库可以实现互相隔离。这是最基本的需求,两个不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求一个类库在一个服务器中只有一份,服务器应当保证两个应用程序的类库可以互相独立使用

    2)部署在同一个服务器上的两个Web应用程序所使用的Java类库可以互相共享。这个需求也非常很常见,如,用户可能有10各使用Spring组织的应用程序部署在同一台服务器上,如果把10份Spring分别存放在各个应用程序的隔离目录中,将会是很大的资源浪费-这主要不是浪费磁盘空间的问题,而是指类库在使用时都要被加载到服务器内存,如果类库不能共享,虚拟机的方法区就会很容易出现过度膨胀的风险

    3)服务器需要尽可能地保证自身的安全不受部署的Web应用程序影响。目前,有许多主流的Java Web服务器自身也是使用Java语言来实现的。因此,服务器本身也有类库依赖的问题,一般来说,基于安全考虑,服务器所使用的类库应该与应用程序的类库相互独立

    4)支持jsp应用的Web服务器,大多数都需要支持HotSwap功能。我们知道,jsp文件最终要编译成Java Class才能由虚拟机执行,但jsp文件由于其纯文本存储的特性,运行时修改的概率远远大于第三方类库或程序自身的Class文件。而且ASP、PHP和JSP这些网页应用也把修改后无需重启作为一个很大的“优势”来看待,因此,“主流”的Web服务器都会支持JSP的热替换,当然也有“非主流”的,如运行在生产模式下的WebLogic服务器默认就不会处理JSP文件的变化

  由于存在上述问题,在部署Web应用时,单独的一个ClassPath就无法满足需求了,所以各种Web服务器都“不约而同”地提供了好几个ClassPath路径供用户存放第三方类库,这些路径一般都以lib或classes命名,被放置到不同路径中的类库,具备不同的访问范围和服务对象,通常,每一个目录都会有一个相应的自定义类加载器去加载放置在里面的Java类库。

  2.Tomcat对用户类库与类加载器的规划

    在其目录结构下有三组目录(“/common/*”、“/server/*”、“/shared/*”)可以存放Java类库,另外还可以加上Web应用程序本身的目录“/WEB-INF/*”,一共4组,把Java类库放置在这些目录中的含义分别如下:

    1)放置在/commom目录中:类库可被Tomcat和所有的Web应用程序共同使用

    2)放置在/server目录中:类库可被Tomcat使用,对所有的Web应用程序都不可见

    3)放置在/shared目录中:类库可被所有的Web应用程序所共同使用,但对Tomcat自己不可见

    4)放置在/WebApp/WEB-INF目录中:类库仅仅可以被此Web应用程序使用,对Tomcat和其他Web应用程序都不可见

    为了支持这套目录结构,并对目录里面的类库进行加载和隔离,Tomcat自定义了多个类加载器,这些类加载器按照经典的双亲委派模型来实现,所下图:

    

    最上面的三个类加载器是JDK默认提供的类加载器,这三个加载器的的作用之前也说过,这里不再赘述了,可以在http://www.cnblogs.com/ghoster/p/7594224.html简单了解。而CommonClassLoader、CatalinaClassLoader、SharedClassLoader和WebAppClassLoader则是Tomcat自己定义的类加载器,他们分别加载/common/*、/server/*、/shared/*和/WebApp/WEB-INF/*中的Java类库。其中WebApp类加载器和jsp类加载器通常会存在多个实例,每一个Web应用程序对应一个WebApp类加载器,每一个jsp文件对应一个Jsp类加载器

    从上图的委派关系可以看出,CommonClassLoader能加载的类都可以被CatalinaClassLoader和SharedClassLoader使用,而CatalinaClassLoader和SharedClassLoader自己能加载的类则与对方相互隔离。WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的哪一个Class,它出现的目的就是为了被丢弃:当服务器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过在建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能

4.打破双亲委派模型企业级应用实战

需求背景:在使用多数据源的情况下,同时连接某大厂魔改的数据库mppdb和pgsql数据库的时候。出现了无法同时加载mppdb和pgsql的驱动的问题。

原因分析:spring在启动时会调用应用类加载器加载org目录下的.class文件,同时spring自定义类加载器分别加载BOOT-INF,META-INF 目录下的文件,mppdb 与pgsql驱动的本质都是.jar文件,所以会放在META-INF目录下的lib目录下。

又因为mppdb是某国内大厂以pgsql为蓝本魔改的,遗留下一个问题,mppdb与mysql驱动的类名是完全一致的。而两驱动都放在lib目录下,由同一个类加载器来加载,就会出现以下情况:当第一个驱动pgsql加载时,使用双亲机制正常加载,

当第二个驱动mppdb再次加载时,会判断该类是否加载过,此时,由于类加载器一致,类名一致,类加载器会误认为mppdb驱动已经加载过了,实际是之前加载的pgsql驱动,所以spring不会再去加载mppdb,而是从缓冲中把pgsql的驱动抛出,

从而导致了,spring在启动时无法同时加载mppdn驱动和pgsql驱动。

解决方案:

方案一:遵循双亲委派模型

在spring容器启动后(此时spring已经加载到其中一个驱动,假设是pgsql驱动),新开一个jvm进程,在该进程中使用扩展类加载器加载mppdb驱动,根据双亲委派模型,扩展类加载器是应用类加载器的父类,当需要加载驱动时会优先委派父类加载,

所以同一个类在父类加载器和子类加载器都能加载的情况下,父类加载器总能优先加载的。这样就保证了,新起的进程总是能加载到扩展类加载器加载的mppdb驱动。

方案二:打破双亲委派模型

在spring容器启动后(此时spring已经加载到其中一个驱动,假设是pgsql驱动),不必新开进程,还是在该spring的进程内,使用应用类加载器XMLClassLoader去加载mppdb驱动,如果此时使用双亲委派模型,会加载到spring初始化时加载到的驱动,即pgsql驱动,

故而 需要将XMLClassLoader 的父加载器设置为null,禁止其父加载器加载,而由其自己加载,即可以成功加载mppdb驱动,具体实现涉及公司信息安全,在此仅提供问题解决思路。

tomcat学习步骤,附带打破双亲委派模型企业应用实战的更多相关文章

  1. Tomcat 类加载器打破双亲委派模型

    我们分为4个部分来探讨: 1. 什么是类加载机制? 2. 什么是双亲委任模型? 3. 如何破坏双亲委任模型? 4. Tomcat 的类加载器是怎么设计的? 我想,在研究tomcat 类加载之前,我们复 ...

  2. 【JVM第二篇--类加载机制】类加载器与双亲委派模型

    写在前面的话:本文是在观看尚硅谷JVM教程后,整理的学习笔记.其观看地址如下:尚硅谷2020最新版宋红康JVM教程 一.什么是类加载器 在类加载过程中,加载阶段有一个动作是"通过一个类的全限 ...

  3. java虚拟机(二)--类加载机制和双亲委派模型

    一.类的生命周期 加载(Loading).验证(Verification).准备(Preparation).解析(Resolution).初始化(Initialization).使用(Using).卸 ...

  4. JDBC、Tomcat为什么要破坏双亲委派模型?

    问题一:双亲委派模型是什么 如果一个类加载器收到了加载某个类的请求,则该类加载器并不会去加载该类,而是把这个请求委派给父类加载器,每一个层次的类加载器都是如此,因此所有的类加载请求最终都会传送到顶端的 ...

  5. JVM总括四-类加载过程、双亲委派模型、对象实例化过程

    JVM总括四-类加载过程.双亲委派模型.对象实例化过程 目录:JVM总括:目录 一. 类加载过程 类加载过程就是将.class文件转化为Class对象,类实例化的过程,(User user = new ...

  6. java类加载器和双亲委派模型

    一. 类加载器 ClassLoader即常说的类加载器,其功能是用于从Class文件加载所需的类,主要场景用于热部署.代码热替换等场景. 系统提供3种的类加载器:Bootstrap ClassLoad ...

  7. Java类加载机制以及双亲委派模型

    一.Java类加载机制 1.概述 Class文件由类装载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获知Class的结构信息:如构造函数,属性和方法等,Java允 ...

  8. Java虚拟机详解(十一)------双亲委派模型

    在上一篇博客,我们介绍了类加载过程,包括5个阶段,分别是“加载”,“验证”,“准备”,“解析”,“初始化”,如下图所示: 本篇博客,我们来介绍Java虚拟机的双亲委派模型,在介绍之前,我先抛出一个问题 ...

  9. 图解JVM类加载机制和双亲委派模型

    我们都知道以 .java 结尾的 Java 源文件,经过编译之后会变成 .class 结尾的字节码文件.JVM 通过类加载器来加载字节码文件,然后再执行程序. 什么时候加载一个类 那么,什么时候类加载 ...

随机推荐

  1. 背水一战 Windows 10 (40) - 控件(导航类): AppBar, CommandBar

    [源码下载] 背水一战 Windows 10 (40) - 控件(导航类): AppBar, CommandBar 作者:webabcd 介绍背水一战 Windows 10 之 控件(导航类) App ...

  2. Linux之IRQ domain

    概述 Linux使用IRQ domain来描述一个中断控制器(IRQ Controller)所管理的中断源.换句话说,每个中断控制器都有自己的domain.我们可以将IRQ Domain看作是IRQ ...

  3. 虚拟机安装centos7

    主要参考这个文档(我已经把网页保存到本地了): http://www.bkjia.com/Linuxjc/867013.html 主要注意: 1.虚拟机网络我选择的桥接模式,在CentOS安装时打开这 ...

  4. iOS,Android,WP, .NET通用AES加密算法

    这两天为移动App开发API,结果实现加密验证时碰到一大坑.这里不得不吐槽下又臭又硬的iOS,Windows Server无法解密出正确的结果,Android则可以,后来使用了通用的AES256加密算 ...

  5. Alpha冲刺(3/10)——追光的人

    1.队友信息 队员学号 队员博客 221600219 小墨 https://www.cnblogs.com/hengyumo/ 221600240 真·大能猫 https://www.cnblogs. ...

  6. vmworkstation安装unbuntu server 网络配置:NAT模式

    之前安装虚拟机测试环境的时候,习惯了使用桥接模式或者仅主机模式:今天偶然发现,其实NAT 模式的网络配置还是挺方便的. 在新建虚拟机的时候,选择网络模式为NAT,虚拟机创建完成之后,在vmworkst ...

  7. 广度优先遍历-BFS、深度优先遍历-DFS

    广度优先遍历-BFS 广度优先遍历类似与二叉树的层序遍历算法,它的基本思想是:首先访问起始顶点v,接着由v出发,依次访问v的各个未访问的顶点w1 w2 w3....wn,然后再依次访问w1 w2 w3 ...

  8. storm_分组策略

      注意1:原始的案例 spout 和bolt都是1个并发  所以文件中30条日志 从spout发出以后 bolt接受到30条

  9. 使用binlog2sql针对mysql进行数据恢复

    MySQL闪回原理与实战 DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚.传统恢复方法是利用备份重搭实例,再应用去除错误sql后的binlog来恢复数据.此法 ...

  10. C#控件事件属性大全

    C#控件及常用设计整 1.窗体... 1 2.Label 控件... 3 3.TextBox 控件... 4 4.RichTextBox控件... 5 5.NumericUpDown 控件... 7 ...