文章目录
- 1. Tomcat 系统架构与原理剖析
- 1.1 浏览器访问服务器的流程
- 1.2 Tomcat 请求处理⼤致过程
- 1.3 Tomcat Servlet容器处理流程
- 1.4 Tomcat 核心组件
- 1.4.1 Coyote 连接器
- 1.4.2 Coyote 的内部组件及流程
- 1.4.3 Tomcat Servlet 容器 Catalina
- 1.4.4 Container 组件的具体结构
- 2. Tomcat 服务器核⼼配置详解
- 3. Tomcat请求处理流程
- 4. Tomcat 类加载机制剖析
- 4.1 JVM 的类加载机制
- 4.2 双亲委派机制
- 4.3 Tomcat 的类加载机制
- 6. Tomcat 对 Https 的⽀持及 Tomcat 性能优化策略
- 6.1 Tomcat 对 HTTPS 的⽀持
1. Tomcat 系统架构与原理剖析
1.1 浏览器访问服务器的流程
1.2 Tomcat 请求处理⼤致过程
Tomcat是⼀个Http服务器(能够接收并且处理http请求,所以tomcat是⼀个http服务器)
我们使⽤浏览器向某⼀个⽹站发起请求,发出的是Http请求,
那么在远程,Http服务器接收到这个请求之后,会调⽤具体的程序(Java类)进⾏处理,往往不同的请求由不同的Java类完成处理。
HTTP 服务器接收到请求之后把请求交给Servlet容器来处理,Servlet 容器通过Servlet接⼝调⽤业务 类。Servlet接⼝和Servlet容器这⼀整套内容叫作Servlet规范。
Tomcat的两个重要身份
- http服务器
- Tomcat是⼀个Servlet容器
1.3 Tomcat Servlet容器处理流程
当⽤户请求某个URL资源时
- HTTP服务器会把请求信息使⽤ServletRequest对象封装起来
- 进⼀步去调⽤Servlet容器中某个具体的Servlet
- 中,Servlet容器拿到请求后,根据URL和Servlet的映射关系,找到相应的Servlet
- 如果Servlet还没有被加载,就⽤反射机制创建这个Servlet,并调⽤Servlet的init⽅法来完成初始化
- 接着调⽤这个具体Servlet的service⽅法来处理请求,请求处理结果使⽤ServletResponse对象封装
- 把ServletResponse对象返回给HTTP服务器,HTTP服务器会把响应发送给客户端
1.4 Tomcat 核心组件
Tomcat 设计了两个核⼼组件连接器(Connector)和容器(Container)
来完成 Tomcat 的两⼤核⼼ 功能。
连接器,负责对外交流: 处理Socket连接,负责⽹络字节流与Request和Response对象的转化;
容器,负责内部处理:加载和管理Servlet,以及具体处理Request请求;
1.4.1 Coyote 连接器
Coyote 是Tomcat 中连接器的组件名称 , 是对外的接⼝。客户端通过Coyote与服务器建⽴连接、发送请 求并接受响应 。
(1)Coyote 封装了底层的⽹络通信(Socket 请求及响应处理)
(2)Coyote 使Catalina 容器(容器组件)与具体的请求协议及IO操作⽅式完全解耦
(3)Coyote 将Socket 输⼊转换封装为 Request 对象,进⼀步封装后交由Catalina 容器进⾏处理,处 理请求完成后, Catalina 通过Coyote 提供的Response 对象将结果写⼊输出流
(4)Coyote 负责的是具体协议(应⽤层)和IO(传输层)相关内容
在 8.0 之前 ,Tomcat 默认采⽤的I/O⽅式为 BIO,之后改为 NIO。 ⽆论 NIO、NIO2 还是 APR, 在性 能⽅⾯均优于以往的BIO。 如果采⽤APR, 甚⾄可以达到 Apache HTTP Server 的影响性能。
1.4.2 Coyote 的内部组件及流程
- EndPoint: EndPoint 是 Coyote 通信端点,即通信监听的接⼝,是具体Socket接收和发送处理器,是对传输层的抽象,因此EndPoint⽤来实现TCP/IP协议的
- Processor 是Coyote 协议处理接⼝ ,如果说EndPoint是⽤来实现TCP/IP协 议的,那么Processor⽤来实现HTTP协议,Processor接收来⾃EndPoint的 Socket,读取字节流解析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理,Processor是对应⽤层协议的抽象
- Coyote 协议接⼝, 通过Endpoint 和 Processor , 实现针对具体协议的处 理能⼒。Tomcat 按照协议和I/O 提供了6个实现类 : AjpNioProtocol , AjpAprProtocol, AjpNio2Protocol , Http11NioProtocol ,Http11Nio2Protocol ,Http11AprProtocol
- 由于协议不同,Tomcat定义了⾃⼰的 Request类来封装这些请求信息。ProtocolHandler接⼝负责解析请求并⽣成 Tomcat Request类。但是这个Request对象不是标准的ServletRequest,不能⽤Tomcat Request作为参数来调⽤容器。引 ⼊CoyoteAdapter,这是适配器模式的经典运⽤,连接器调⽤ CoyoteAdapter的Sevice⽅法,传⼊的是Tomcat Request对象,CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调⽤容器
1.4.3 Tomcat Servlet 容器 Catalina
Tomcat是⼀个由⼀系列可配置(conf/server.xml)的组件构成的Web容器,⽽Catalina是Tomcat的 servlet容器。
从另⼀个⻆度来说,Tomcat 本质上就是⼀款 Servlet 容器, 因为 Catalina 才是 Tomcat 的核⼼ , 其 他模块都是为Catalina 提供⽀撑的。 ⽐如 : 通过 Coyote 模块提供链接通信,Jasper 模块提供 JSP 引擎,Naming 提供JNDI 服务,Juli 提供⽇志服务。
1.4.4 Container 组件的具体结构
Container组件下有⼏种具体的组件,分别是Engine、Host、Context和Wrapper。这4种组件(容器)
是⽗⼦关系。Tomcat通过⼀种分层的架构,使得Servlet容器具有很好的灵活性
- Engine 表示整个Catalina的Servlet引擎,⽤来管理多个虚拟站点,⼀个Service最多只能有⼀个Engine, 但是⼀个引擎可包含多个Host
- Host代表⼀个虚拟主机,或者说⼀个站点,可以给Tomcat配置多个虚拟主机地址,⽽⼀个虚拟主机下 可包含多个Context
- Context 表示⼀个Web应⽤程序, ⼀个Web应⽤可包含多个Wrapper
- Wrapper表示⼀个Servlet,Wrapper 作为容器中的最底层,不能包含⼦容器
2. Tomcat 服务器核⼼配置详解
核⼼配置在tomcat⽬录下conf/server.xml⽂件
- tomcat 作为服务器的配置,主要是 server.xml ⽂件的配置;
- server.xml中包含了 Servlet容器的相关配置,即 Catalina 的配置;
- Xml ⽂件的讲解主要是标签的使⽤
3. Tomcat请求处理流程
4. Tomcat 类加载机制剖析
Java类(.java)—> 字节码⽂件(.class) —> 字节码⽂件需要被加载到jvm内存当中(这个过程就是⼀个 类加载的过程)
类加载器(ClassLoader,说⽩了也是⼀个类,jvm启动的时候先把类加载器读取到内存当中去,其他的 类(⽐如各种jar中的字节码⽂件,⾃⼰开发的代码编译之后的.class⽂件等等))
要说 Tomcat 的类加载机制,⾸先需要来看看 Jvm 的类加载机制,因为 Tomcat 类加载机制是在 Jvm 类加载机制基础之上进⾏了⼀些变动。
4.1 JVM 的类加载机制
JVM 的类加载机制中有⼀个⾮常重要的⻆⾊叫做类加载器(ClassLoader),类加载器有⾃⼰的体系, Jvm内置了⼏种类加载器,包括:引导类加载器、扩展类加载器、系统类加载器,他们之间形成⽗⼦关系,通过 Parent 属性来定义这种关系,最终可以形成树形结构。
自定义类加载器 -> 系统类加载器 -> 扩展类加载器 -> 引导类加载器
引导启动类加载器 BootstrapClassLoader:
c++编写,加载java核⼼库 java.*,⽐如rt.jar中的类,构 造ExtClassLoader和AppClassLoader
扩展类加载器 ExtClassLoade
java编写,加载扩展库 JAVA_HOME/lib/ext⽬录下的jar 中的类,如classpath中的jre ,javax.*或者java.ext.dir
指定位置中的类
系统类加载器 SystemClassLoader/AppClassLoader
默认的类加载器,搜索环境变量 classpath 中指明的路 径
当 JVM 运⾏过程中,⽤户⾃定义了类加载器去加载某些类时,会按照下⾯的步骤(⽗类委托机制)
1) ⽤户⾃⼰的类加载器,把加载请求传给⽗加载器,⽗加载器再传给其⽗加载器,⼀直到加载器树的顶层
2 )最顶层的类加载器⾸先针对其特定的位置加载,如果加载不到就转交给⼦类
3 )如果⼀直到底层的类加载都没有加载到,那么就会抛出异常 ClassNotFoundException 因此,按照这个过程可以想到,如果同样在 classpath 指定的⽬录中和⾃⼰⼯作⽬录中存放相同的class,会优先加载 classpath ⽬录中的⽂件
4.2 双亲委派机制
当某个类加载器需要加载某个.class⽂件时,它⾸先把这个任务委托给他的上级类加载器,递归这个操
作,如果上级的类加载器没有加载,⾃⼰才会去加载这个类。
防⽌重复加载同⼀个.class。通过委托去向上⾯问⼀问,加载过了,就不⽤再加载⼀遍。保证数据 安全。
保证核⼼.class不能被篡改。通过委托⽅式,不会去篡改核⼼.class,即使篡改也不会去加载,即使 加载也不会是同⼀个.class对象了。不同的加载器加载同⼀个.class也不是同⼀个.class对象。这样 保证了class执⾏安全(如果⼦类加载器先加载,那么我们可以写⼀些与java.lang包中基础类同名 的类, 然后再定义⼀个⼦类加载器,这样整个应⽤使⽤的基础类就都变成我们⾃⼰定义的类了。 )
Object类 -----> ⾃定义类加载器(会出现问题的,那么真正的Object类就可能被篡改了)
4.3 Tomcat 的类加载机制
Tomcat 的类加载机制相对于 Jvm 的类加载机制做了⼀些改变。
没有严格的遵从双亲委派机制,也可以说打破了双亲委派机制
⽐如:有⼀个tomcat,webapps下部署了两个应⽤ app1/lib/a-1.0.jar com.lagou.edu.Abc app2/lib/a-2.0.jar com.lagou.edu.Abc
不同版本中Abc类的内容是不同的,代码是不⼀样的
6. Tomcat 对 Https 的⽀持及 Tomcat 性能优化策略
6.1 Tomcat 对 HTTPS 的⽀持
Http超⽂本传输协议,明⽂传输 ,传输不安全,https在传输数据的时候会对数据进⾏加密 ssl协议 TLS(transport layer security)协议
HTTPS和HTTP的主要区别
- HTTPS协议使⽤时需要到电⼦商务认证授权机构(CA)申请SSL证书
- HTTP默认使⽤8080端⼝,HTTPS默认使⽤8443端⼝
- HTTPS则是具有SSL加密的安全性传输协议,对数据的传输进⾏加密,效果上相当于HTTP的升级 版
- HTTP的连接是⽆状态的,不安全的;HTTPS协议是由SSL+HTTP协议构建的可进⾏加密传输、身份认证的⽹络协议,⽐HTTP协议安全