一、Tomcat基础知识与运行原理
本章节为介绍如何安装Tomcat工具以及其主要架构知识概念,深入浅出让新人玩家理解为什么选择该容器以及该容器的优点
web服务器
概念
服务器:安装了服务器软件的计算机
服务器软件:接收用户的请求,处理请求,做出响应
web服务器软件:接收用户的请求,处理请求,做出响应。
在web服务器软件中,可以部署web项目,让用户通过浏览器来访问这些项目
常见web服务器软件
1、webLogic:oracle公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费。
2、websphere:IBM公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费。
3、JBOSS:JBOSS公司的,大型的JavaEE服务器,支持所有的JavaEE规范,收费。
4、Tomcat:Apache基金组织,中小型的JavaEE服务器,仅仅支持少量的JavaEE规范servlet/jsp。开源、免费。
Tomcat
一、Tomcat 安装
下载
https://tomcat.apache.org/download-80.cgi
apache-tomcat-8.5.42-windows-x64.zip
安装
将下载的.zip 压缩包解压到系统的目录(建议是没有中文不带空格的目录)下即可。
目录结构如图:

二、Tomcat源码
下载
地址:https://tomcat.apache.org/download-80.cgi
apache-tomcat-8.5.42-src.zip
运行
1)解压zip压缩包
2)进入解压目录,并创建一个目录,命名为home ,并将conf、webapps日录移入home目录中
3)在当前目录下创建一个pom.xml文件,引入tomcat的依赖包
HTTP服务器的请求处理原理

servlet容器的工作流程
HTTP服务器不直接调用servlet,而是把请求交给servlet容器来处理
问:那servlet容器是怎么工作的?
当客户请求某个资源时,HTTP服务器会用一个servletRequest对象把客户的请求信息封装起来,然后调用servlet容器的service方法,
servlet容器金到请求后,根据请求的URI和servlet的映射关系,找到相应的servlet,如果servlet还没有被加载,就用反射机制创建这个servlet,
并调用servlet的init方法来完成初始化,接着调用servlet的service方法来处理请求,把servletResponse对象返回给HTTP服务器,HTTP服务器会把响应发送给客户端。

三、Tomcat整体架构
我们知道如果要设计一个系统,首先是要了解需求,而我们已经了解了Tomcat要实现两个核心功能:
1)处理socket连接,负责网络字节流与Request和Response对象的转化。
2)加载和管理servlet,以及具体处理Reguest请求。
因此Tomcat设计了两个核心组件连接器(connector)和容器(container)来分别做这两件事情,连接器负责对外交流,容器负责内部处理。

连接器Coyote
Coyote 是Tomcat的连接器框架的名称,是Tomcat服务器提供的供客户端访问的外部接口。
客户端通过Coyote与服务器建立连接、发送请求并接受响应。
1)Coyote封装了底层的网络通信(Socket 请求及响应处理),为Catalina 容器提供了统一的接口,使Catalina容器与具体的请求协议及I0操作方式完全解耦。
2)Coyote将Socket输入转换封装为Request对象,交由catalina容器进行处理,处理完成后,Catalina 通过Coyote提供的Response对象将结果写入输出流。
3)Coyote作为独立的模块,只负责具体协议和I0 的相关操作,与Servlet规范实现没有直接关系,因此即便是Request和Response对象也并未实现servlet规范对应的接口,
而是在Catalina中将他们进一步封装为servletRequest 和ServletResponse。
Io模型与协议
在Coyote中
Tomcat支持的多种I/O模型和应用层协议,具体包含的IO模型和应用层协议,看下表
Tomcat支持的IO模型(自8.5/9.0 版本起,Tomcat 移除了 对 BI0 的支持):
| IO模型 | 描述 |
|---|---|
| NIO | 非阻塞I/0,采用Java NIo类库实现。 |
| NIO2 | 异步I/0,采用JDK 7最新的NIO2类库实现。 |
| APR | 采用apache可移植运行库实现,是c/c++编写的本地库。如果选择该方案,需要单独安装APR库 |
Tomcat 支持的应用层协议:
| 应用层协议 | 描述 |
|---|---|
| HTTP/1.1 | 这是大部分web应用采用的访问协议。 |
| AJP | 用于和web服务器集成(如Apache),以实现对静态资源的优化以及集群部署,当前支持AJP/1.3。 |
| HTTP/2 | HTTP 2.0大幅度的提升了web性能。下一代HTTP协议,自8.5以及9.0版本之后支持。 |

Tomcat中的组件
一、连接器组件

连接器的组件对数据处理的流程简介
客户端发起的Socket请求会被EndPoint接收并且会把请求发送给处理器processor,processor在接受到请求之后将该请求转换成http协议的请求,
并将http的请求进行解析封装成request对象,但是容器需要的是ServletRequest对象,所以Tomcat用到了设计模式-适配器设计模式,先调用adapter(适配器)的转换方法将Request对象转换成servletRequest对象再传输给容器。
连接器中的各个组件的作用
1、EndPoint组件
1、EndPoint:Coyote通信端点,即通信监听的接口,是具体Socket接收和发送处理器,是对传输层的抽象,因此Endpoint用来实现TCP/IP协议的。
2、Tomcat并没有Endpoint接口,而是提供了一个抽象类abstractEndpoint,里面定义了两个内部类:acceptor和Socketprocessor。
Acceptor用于监听Socket连接请求。socket processor用于处理接收到的socket请求,它实现Runnable接口,在Run方法里调用协议处理组件processor进行处理,为了提高处理能力,
socketprocessor被提交到线程池来执行。而这个线程池叫作执行器(Executor),(后面再详细介绍Tomcat如何扩展原生的Java线程池)
2、Processor组件
Processor:Coyote协议处理接口如果说Endpoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议,Processor接收来自Endpoint的socket,
读取字节流解析成Tomcat Recuest和Response对象,并通过Adapter将其提交到容器处理,processor是对应用层协议的抽象。
3、ProtocolHandler组件
ProtocolHandler:Coyote协议接口,通过Endpoint和Processor ,实现针对具体协议的处理能力。Tomcat按照协议和I/O 提供了6个实现类:
AjpNio2Protocol、AjpAprProtocol、Http11Nio2Protocol、AjpNio2Protoco1,Http11NioProtoco1、Http11Aprprotocol,在配置tomcat/conf/server.xml 时,至少要指定具体的ProtocolHandler,当然也可以指定协议名称,如:HTTP/1.1,如果安装了APR,那么将使用nttp11Aprprotocol ,否则使用 Http11Nioprotocol
4、Adapter组件
由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类来”存放”这些请求信息。Protoco1Hand1er接口负责解析请求并生成Tomcat Reguest类。但是这个Reguest对象不是标准的servletReguest,也就意味着,不能用omcat Request作为参数来调用容器。Tomcat设计者的解决方案是引入coyoteAdapter,这是适配器模式的经典运用,连接器调用covoteAdapter的Sevice方法,传入的是Tomcat Request对象,CoyoteAdapter负责将Tomcat Reguest转成servletRequest,再调用容器的service方法。
二、容器-Catalina
概念
如果说coyote是负责具体的协议的解析,那么 Catalina就是对最终的请求逻辑进行处理。
介绍
Tomcat是一个由一系列可配置的组件构成的web容器,而catalina是Tomcat的servlet容器
catalina是servlet容器实现,包含了之前讲到的所有的容器组件,以及后续章节涉及到的安全、会话、集群、管理等servlet 容器架构的各个方面。
它通过松耦合的方式集成coyote,以完成按照请求协议进行数据读写。同时,它还包括我们的启动入口、shell程序等。
Catalina的地位可以通过下图的Tomcat的分层结构示意图来帮助了解

微总结
Tomcat 本质上是一款Servlet 容器,因此Catalina才是Tomcat的核心其他模块都是为Catalina提供支撑的。
比如通过Coyote模块提供链接通信,Jasper 模块提供JSP引擎,Naming 提供JNDI 服务,Juli提供日志服务。
结构
为帮助理解Catalina的结构用下图进行展示

如上图所示,catalina负责管埋server,而server表示着整个服务器。server下面有多个服务service,每个服务都包含着多个连接器组件connector(coyote实现)和一个容器组件container。在Tomcat 启动的时候, 会初始化一个catalina的实例。
Catalina各组件的职责
| 组件 | 职责 |
|---|---|
| Catalina | 负责解析Tomcat的配置文件:,以此来创建服务器server组件,并根据命令来对其进行管理 |
| Server | 服务器表示整个catalina servlet容器以及其它组件,负责组装并启动servlet引擎,Tomcat连接器。server通过实现Lifecycle接口,提供启动和关闭整个系统的方式 |
| Service | 服务是server内部的组件,一个server包含多个service。它将若干个connector组件绑定到一个Container(Engine)上 |
| Connector | 连接器,处理与客户端的通信,它负责接收客户请求,然后转给相关的容器处理,最后向客户返回响应结果 |
| Container | 容器,负责处理用户的servlet请求,并返回对象给web用户的模块 |
| 1、Container容器结构说明 | |
| Tomcat设计了4种容器,分别是Engine、Host、Context和wrapper。这4种容器不是平行关系,而是父子关系。 | |
| Tomcat通过一种分层的架构,使得servlet容器具有很好的灵活性。 | |
![]() |
也可以再通过tomcat的server.xml配置文件来加深对Tomcat容器的理解。
Tomcat采用了组件化的设计,它的构成组件都是可配置的,其中最外层的是server,其他组件按照一定的格式要求配置在这个顶层容器中。
<service>
<Connector/>
<Connector/>
<Engine>
<Host>
<Context></Context>
</Host>
</Engine>
</service>
</server>
Tomcat是如何管理这些容器的?
这些容器具有父子关系,形成一个树形结构,在这里你可能马上就想到了设计模式中的组合模式。
没错Tomcat就是用组合模式来管理这些容器的。
具体实现方法是,所有容器组件都实现了container接口,因此组合模式可以使得用户对单容器对象和组合容器对象的使用具有一致性,
这里单容器对象指的是最底层的wrapper,组合容器对象指的是上面的context、Host或者Engine。
三、Tomcat 启动流程
1、启动步骤:
1)启动tomcat需要调用 bin/startup.bat(在linux目录下,需要调用 bin/startup.sh)在startup.bat 脚本中调用了catalina.bat。
2)在Catalina.bat脚本文件中调用了 Bootstrap 中的main方法。
3)在Bootstrap的main方法中调用了 init 方法来创建catalina 及 初始化类加载器。
4)在Bootstrap的main方法中调用了 load 方法,在其中又调用了catalina的load方法。
5)在catalina的load方法中,需要进行一些初始化的工作,并需要构造Digester 对象,用于解析XML.然后在调用后续组件的初始化操作。。。
其实就是加载Tomcat的配置文件,初始化容器组件,监听对应的端口号,准备接受客户端请求。

2、源码解析:
lifecycle
由于所有的组件均存在初始化、启动、停止等生命周期方法,拥有生命周期管理的特性,所以Tomcat在设计的时候,基于生命周期管理抽象成了一个接口lifecycle,
而组件server、service、container、Executor、connector 组件,都实现了一个生命周期的接口,从而具有了以下生命周期中的核心方法:
- init():初始化组件
- start():启动组件
- stop():停止组件
- destroy():销毁组件

各组件的默认实现
上述的server、service、Engine、Host、context都是接口,下图中罗列的这些接口的默认实现类。
当前对于Endpoint组件来说,在Tomcat中没有对应的Endpoint接口,但是有一个抽象类AbstractEndpoint,其下有三个实现类:
NioEndpoint、Nio2Endpoint、AprEndpoint这三个实现类,分别对应于前面的链接器Coyote提到的链接器支持的三种IO模型:
NIO,NIO2,APR,Tomcat8.5版本中,默认采用的是 NioEndpoint。

ProtocolHandler:Coyote协议接口,通过封装Endpoint和Processor(相当于Endpoint和Processor组合的组件)实现针对具体协议的处理功能。
Tomcat按照协议和IO提供了6个实现类:
AJP协议:
1)AjpNioProtocol :采用NIO的IO模型
2)AjpNio2protocol:采用NI02的IO模型
3)Ajpaprprotocol :采用APR的IO模型,需要依赖于APR库
HTTP协议:
1)Httpl1NioProtocol:采用NIO的Io模型,默认使用的协议(如果服务器没有安装APR)。
2)Http11Nio2Protoco1:采用NIO2的IO模型。
3)Httpl1aprProtocol:采用APR的IO模型,需要依赖于APR库。

启动流程(暂时先不做补充)
https://www.bilibili.com/video/BV1dJ411N7Um?p=13&spm_id_from=pageDriver&vd_source=ae9c1573e924540a89e008b340e54657
xxx
xxx
xxx
请求处理流程
设计了这么多层次的容器,Tomcat是怎么确定每一个请求应该由哪个Wrapper容器里的servlet来处理的呢?
答案是,Tomcat是用Mapper组件来完成这个任务的。
Mapper组件的功能是将用户请求的URL定位到一个servlet,它的工作原理是在Mapper组件里保存了web应用的配置信息,也就是容器组件与访问路径的映射关系,比如:
Host容器里配置的域名、context容器里的neb应用路径,以及wrapper容器里servlet映射的路径,可以理解为这些配置信息就是一个多层次的Map。
当一个请求到来时Mapper组件通过解析请求URL里的域名和路径,再到自己保存的Map里去查找,就能定位到一个servlet。
注意。一个请求URL最后只会定位到一个wrapper容器,也就是一个servlet。
下面的示意图中就描述了 当用户请求链接 http://www.itcast.cn/bbs/findA11之后,是如何找到最终处理业务逻辑的servlet。


一、Tomcat基础知识与运行原理的更多相关文章
- php基础知识(语法与原理)
一.php简介 PHP超文本预处理器.是嵌入HTML文件中的服务器脚本程序. PHP代码标记:<?php …. ?> PHP文件的扩展名:.php PHP文件的执行:必须从域名开始访问 P ...
- tomcat 基础知识学习
1: 直接将web项目文件件拷贝到webapps 目录中,Tomcat的Webapps目录是Tomcat默认的应用目录,当服务器启动时,会加载所有这个目录下的应用,所以可以将JSP程序打包成一个 wa ...
- Tomcat基础知识
介绍Tomcat之前先介绍下Java相关的知识. 各常见组件: 1.服务器(server):Tomcat的一个实例,通常一个JVM只能包含一个Tomcat实例:因此,一台物理服务器上可以在启动多个JV ...
- 【基础知识】CPU原理之减法、乘法和除法
中介绍了布尔逻辑.数学和电路的关系,我们也得到了与门.或门.非门.或非门.与非门.异或门等门电路以及一个加法器,并且了解了计算机是如何做加法的,这篇文章介绍一下计算机是如何做减法以及乘除法的. 0x0 ...
- FPGA基础知识了解
FPGA学习的一些误区 FPGA入门必看资源 FPGA百度百科 FPGA基础知识及其工作原理 高端设计工具为少有甚是没有硬件设计技术的工程师和科学家提供现场可编程门阵列(FPGA).无论你使用图形化设 ...
- Js基础知识(四) - js运行原理与机制
js运行机制 本章了解一下js的运行原理,了解了js的运行原理才能写出更优美的代码,提高运行效率,还能解决开发中遇到的不理解的问题. 进程与线程 进程是cpu资源分配的最小单位,进程可以包含多个线程. ...
- Web自动化必会知识:「Web基础、元素定位、元素操作、Selenium运行原理、项目实战+框架」
1.web 基础-html.dom 对象.js 基本语法 Dom 对象里面涉及元素定位以及对元素的修改.因为对元素操作当中涉及的一些 js 操作,js 基本语法要会用.得要掌握前端的基本用法.为什么要 ...
- Java基础知识强化之多线程笔记05:Java程序运行原理 和 JVM的启动是多线程的吗
1. Java程序运行原理: Java 命令会启动Java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程.该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 m ...
- 【WEB】Tomcat基础使用知识
由于当前项目性质原因,从开始到现在使用的WEB服务器都是WAS,而Tomcat的基础知识也慢慢地被遗忘.由于种种原因,让我参与到了另外一个全新的项目,使用的是Tomcat6.X,所以复习是必须的,而写 ...
- Java基础—Java运行原理
Java程序运行原理 在Java中引入了虚拟机(JVM,Java Virtual Machine)的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.虚拟机在任何平台上都提供给编译程序一个的共同 ...
随机推荐
- 深度学习用什么卡比较给力?—— A100/H100真的么有RTX4090好吗?
近日看到这么一个帖子: https://www.zhihu.com/question/612568623/answer/3131709693 ============================= ...
- 如何快速在 Apache DolphinScheduler 新扩展一个任务插件?
作者 | 代立冬 编辑 | Debra Chen Apache DolphinScheduler 是现代数据工作流编排平台,具有非常强大的可视化能力,DolphinScheduler 致力于使数据工程 ...
- 社区6月月报 | Apache SeaTunnel重要更新与优化记录
各位热爱Apache SeaTunnel的小伙伴们,社区6月份月报来啦!这里将记录Apache SeaTunnel社区每月的重要更新,欢迎关注. 月度Merge Stars 感谢以下小伙伴上个月为Ap ...
- 瑞芯微rk356x板子快速上手
@ 目录 rk3568 CPU GPU NPU VPU 一.编译环境要求 二.编译前准备 0)开发板型号 1)安装第三方编译工具 2)设置adb路径 3)安装USB驱动DriverAssitant_v ...
- P4823 [TJOI2013] 拯救小矮人
感觉这个题的操作很新奇,做个记录. P4823 [TJOI2013] 拯救小矮人 大概题面: 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决 定搭一个人梯.即:一个小矮人站在另一小矮人 ...
- 海康威视测速&闪速测速
海康威视64g 闪速128g
- java_父类子类
private 只有自身能访问自身 自身 同包子 不同包子类 同包类 其他类 可以访问 不能继承 不能继承 不能访问 不能访问 package/friendly/default == 不写 自身 同包 ...
- 最详细STL(四)priority_queue
好吧,开始累了,不想写那么多废话了,直接讲对打oj有用的部分吧. priority_queue是由堆来实现的,底层是用vector来实现的,接收三个参数 priority_queue<int , ...
- React的prop-types下载安装教程
最近刚入门react,所有react的资源都是从本地导入的,这就难免要去网上找要用的包,react包和reactdom,还有babel的包都挺好找的,官网就有现成的可以用,但是prop-types包貌 ...
- Go context 介绍
在 Go 编程语言中,context 包提供了一个用于在 goroutine 之间传递上下文信息的方法.它通常用于控制 goroutine 的生命周期.传递请求范围内的数据.以及处理超时或取消信号.c ...
