一.Tomcat 基础

1.1.Tomcat 基础

Tomcat 本质上就是一款 Servle(色为) 容器, 因此Catalina(卡塔琳娜)才是 Tomcat 的核心 , 其他模块都是为Catalina(卡塔琳娜) 提供支撑的。 比如 : 通过Coyote (k有你)模块提供链接通信,Jasper(贾斯珀) 模块提供JSP引擎,Naming 提供JNDI 服务,Juli 提供日志服务。1). 软件架构1. C/S: 客户端/服务器端 ‐‐‐‐‐‐‐‐‐‐‐‐> QQ , 360 ....2. B/S: 浏览器/服务器端 ‐‐‐‐‐‐‐‐‐‐‐‐> 京东, 网易 , 淘宝 , 传智播客官网2). 资源分类1. 静态资源: 所有用户访问后,得到的结果都是一样的,称为静态资源。静态资源可以直接被浏览器解析。* 如: html,css,JavaScript,jpg2. 动态资源: 每个用户访问相同资源后,得到的结果可能不一样 , 称为动态资源。动态资源被访问后,需要先转换为静态资源,再返回给浏览器,通过浏览器进行解析。* 如:servlet/jsp,php,asp....3). 网络通信三要素1. IP:电子设备(计算机)在网络中的唯一标识。2. 端口:应用程序在计算机中的唯一标识。 0~655363. 传输协议:规定了数据传输的规则1. 基础协议:1. tcp : 安全协议,三次握手。 速度稍慢2. udp:不安全协议。 速度

为什么会有TCP/IP协议?

在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是千差万别。就好像圣经中上帝打乱了各地人的口音,让他们无法合作一样。计算机使用者意识到,计算机只是单兵作战并不会发挥太大的作用。只有把它们联合起来,电脑才会发挥出它最大的潜力。于是人们就想方设法的用电线把电脑连接到了一起。

但是简单的连到一起是远远不够的,就好像语言不同的两个人互相见了面,完全不能交流信息。因而他们需要定义一些共通的东西来进行交流,TCP/IP就是为此而生。TCP/IP不是一个协议,而是一个协议族的统称。里面包括了IP协议,IMCP协议,TCP协议,以及我们更加熟悉的http、ftp、pop3协议等等。电脑有了这些,就好像学会了外语一样,就可以和其他的计算机终端做自由的交流了。

TCP/IP协议分层 TCP/IP协议族按照层次由上到下,层层包装。

应用层:向用户提供一组常用的应用程序,比如电子邮件、文件传输访问、远程登录等。远程登录TELNET使用TELNET协议提供在网络其它主机上注册的接口。TELNET会话提供了基于字符的虚拟终端。文件传输访问FTP使用FTP协议来提供网络内机器间的文件拷贝功能。

传输层:提供应用程序间的通信。其功能包括:一、格式化信息流;二、提供可靠传输。为实现后者,传输层协议规定接收端必须发回确认,并且假如分组丢失,必须重新发送。

网络层 :负责相邻计算机之间的通信。其功能包括三方面。一、处理来自传输层的分组发送请求,收到请求后,将分组装入IP数据报,填充报头,选择去往信宿机的路径,然后将数据报发往适当的网络接口。

二、处理输入数据报:首先检查其合法性,然后进行寻径--假如该数据报已到达信宿机,则去掉报头,将剩下部分交给适当的传输协议;假如该数据报尚未到达信宿,则转发该数据报。

三、处理路径、流控、拥塞等问题。

网络接口层:这是TCP/IP软件的最低层,负责接收IP数据报并通过网络发送之,或者从网络上接收物理帧,抽出IP数据报,交给IP层。

IP 是无连接的IP 用于计算机之间的通信。

IP 是无连接的通信协议。它不会占用两个正在通信的计算机之间的通信线路。这样,IP 就降低了对网络线路的需求。每条线可以同时满足许多不同的计算机之间的通信需要。

通过 IP,消息(或者其他数据)被分割为小的独立的包,并通过因特网在计算机之间传送。

IP 负责将每个包路由至它的目的地。

IP地址每个计算机必须有一个 IP 地址才能够连入因特网。

每个 IP 包必须有一个地址才能够发送到另一台计算机。

网络上每一个节点都必须有一个独立的Internet地址(也叫做IP地址)。现在,通常使用的IP地址是一个32bit的数字,也就是我们常说的IPv4标准,这32bit的数字分成四组,也就是常见的255.255.255.255的样式。IPv4标准上,地址被分为五类,我们常用的是B类地址。具体的分类请参考其他文档。需要注意的是IP地址是网络号+主机号的组合,这非常重要。

CP/IP 使用 32 个比特来编址。一个计算机字节是 8 比特。所以 TCP/IP 使用了 4 个字节。一个计算机字节可以包含 256 个不同的值:00000000、00000001、00000010、00000011、00000100、00000101、00000110、00000111、00001000 ....... 直到 11111111。现在,你知道了为什么 TCP/IP 地址是介于 0 到 255 之间的 4 个数字。TCP 使用固定的连接TCP 用于应用程序之间的通信。

当应用程序希望通过 TCP 与另一个应用程序通信时,它会发送一个通信请求。这个请求必须被送到一个确切的地址。在双方“握手”之后,TCP 将在两个应用程序之间建立一个全双工 (full-duplex) 的通信。

这个全双工的通信将占用两个计算机之间的通信线路,直到它被一方或双方关闭为止。

UDP 和 TCP 很相似,但是更简单,同时可靠性低于 TCP。

IP 路由器当一个 IP 包从一台计算机被发送,它会到达一个 IP 路由器。

IP 路由器负责将这个包路由至它的目的地,直接地或者通过其他的路由器。

在一个相同的通信中,一个包所经由的路径可能会和其他的包不同。而路由器负责根据通信量、网络中的错误或者其他参数来进行正确地寻址。

域名12 个阿拉伯数字很难记忆。使用一个名称更容易。

用于 TCP/IP 地址的名字被称为域名。w3school.com.cn 就是一个域名。

当你键入一个像 http://www.w3school.com.cn 这样的域名,域名会被一种 DNS 程序翻译为数字。

在全世界,数量庞大的 DNS 服务器被连入因特网。DNS 服务器负责将域名翻译为 TCP/IP 地址,同时负责使用新的域名信息更新彼此的系统。

当一个新的域名连同其 TCP/IP 地址一同注册后,全世界的 DNS 服务器都会对此信息进行更新。

TCP/IPTCP/IP 意味着 TCP 和 IP 在一起协同工作。

TCP 负责应用软件(比如你的浏览器)和网络软件之间的通信。

IP 负责计算机之间的通信。

TCP 负责将数据分割并装入 IP 包,然后在它们到达的时候重新组合它们。

IP 负责将包发送至接受者。

TCP报文格式

16位源端口号:16位的源端口中包含初始化通信的端口。源端口和源IP地址的作用是标识报文的返回地址。

16位目的端口号:16位的目的端口域定义传输的目的。这个端口指明报文接收计算机上的应用程序地址接口。

32位序号:32位的序列号由接收端计算机使用,重新分段的报文成最初形式。当SYN出现,序列码实际上是初始序列码(Initial Sequence Number,ISN),而第一个数据字节是ISN+1。这个序列号(序列码)可用来补偿传输中的不一致。

32位确认序号:32位的序列号由接收端计算机使用,重组分段的报文成最初形式。如果设置了ACK控制位,这个值表示一个准备接收的包的序列码。

4位首部长度:4位包括TCP头大小,指示何处数据开始。

保留(6位):6位值域,这些位必须是0。为了将来定义新的用途而保留。

标志:6位标志域。表示为:紧急标志、有意义的应答标志、推、重置连接标志、同步序列号标志、完成发送数据标志。按照顺序排列是:URG、ACK、PSH、RST、SYN、FIN。

16位窗口大小:用来表示想收到的每个TCP数据段的大小。TCP的流量控制由连接的每一端通过声明的窗口大小来提供。窗口大小为字节数,起始于确认序号字段指明的值,这个值是接收端正期望接收的字节。窗口大小是一个16字节字段,因而窗口大小最大为65535字节。

16位校验和:16位TCP头。源机器基于数据内容计算一个数值,收信息机要与源机器数值 结果完全一样,从而证明数据的有效性。检验和覆盖了整个的TCP报文段:这是一个强制性的字段,一定是由发送端计算和存储,并由接收端进行验证的。

16位紧急指针:指向后面是优先数据的字节,在URG标志设置了时才有效。如果URG标志没有被设置,紧急域作为填充。加快处理标示为紧急的数据段。

选项:长度不定,但长度必须为1个字节。如果没有选项就表示这个1字节的域等于0。

数据:该TCP协议包负载的数据。在上述字段中,6位标志域的各个选项功能如下。

URG:紧急标志。紧急标志为"1"表明该位有效。ACK:确认标志。表明确认编号栏有效。大多数情况下该标志位是置位的。TCP报头内的确认编号栏内包含的确认编号(w+1)为下一个预期的序列编号,同时提示远端系统已经成功接收所有数据。PSH:推标志。该标志置位时,接收端不将该数据进行队列处理,而是尽可能快地将数据转由应用处理。在处理Telnet或rlogin等交互模式的连接时,该标志总是置位的。RST:复位标志。用于复位相应的TCP连接。SYN:同步标志。表明同步序列编号栏有效。该标志仅在三次握手建立TCP连接时有效。它提示TCP连接的服务端检查序列编号,该序列编号为TCP连接初始端(一般是客户端)的初始序列编号。在这里,可以把TCP序列编号看作是一个范围从0到4,294,967,295的32位计数器。通过TCP连接交换的数据中每一个字节都经过序列编号。在TCP报头中的序列编号栏包括了TCP分段中第一个字节的序列编号。FIN:结束标志。

TCP三次握手

(1)第一次握手:Client(快了)将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

(2)第二次握手:Server(色我)收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

(3)第三次握手:Client(快了)收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server(色我),Server(色我)检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client(快了)与Server(色我)之间可以开始传输数据了。

简单来说,就是

1、建立连接时,客户端发送SYN包(SYN=i)到服务器,并进入到SYN-SEND状态,等待服务器确认

2、服务器收到SYN包,必须确认客户的SYN(ack=i+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器进入SYN-RECV状态

3、客户端收到服务器的SYN+ACK包,向服务器发送确认报ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手,客户端与服务器开始传送数据。

TCP四次挥手

由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。

(1)第一次挥手:Client发送一个FIN,用来关闭Client(快了)到Server(色我)的数据传送,Client(快了)进入FIN_WAIT_1状态。

(2)第二次挥手:Server(色我)收到FIN后,发送一个ACK给Client(快了),确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server(色我)进入CLOSE_WAIT状态。

(3)第三次挥手:Server发送一个FIN,用来关闭Server(色我)到Client(快了)的数据传送,Server(色我)进入LAST_ACK状态。

(4)第四次挥手:Client(快了)收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server(色我),确认序号为收到序号+1,Server(色我)(色我)进入CLOSED状态,完成四次挥手。

为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close(可欧的),也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。

1.2 Tomcat 目录结构 Tomcat 的主要目录文件如下 :

bin / 存放Tomcat的启动、停止等批处理脚本文件startup.bat ,startup.sh用于在windows和linux下的启动脚本shutdown.bat ,shutdown.sh用于在windows和linux下的停止脚本conf / 用于存放Tomcat的相关配置文件Catalina 用于存储针对每个虚拟机的Context配置context.xml用于定义所有web应用均需加载的Context配置,如果web应用指定了自己的context.xml,该文件将被覆盖catalina.properties Tomcat 的环境变量配置catalina.policy Tomcat 运行的安全策略配置logging.propertiesTomcat 的日志配置文件, 可以通过该文件修改Tomcat 的日志级别及日志路径等server.xml Tomcat 服务器的核心配置文件tomcat-users.xml 定义Tomcat默认的用户及角色映射信息配置web.xmlTomcat 中所有应用默认的部署描述文件, 主要定义了基础Servlet和MIME映射。lib / Tomcat 服务器的依赖包logs / Tomcat 默认的日志存放目录webapps / Tomcat 默认的Web应用部署目录work / Web 应用JSP代码生成和编译的临时目录

二.Tomcat 架构 2.1 Http工作原理

HTTP协议是浏览器与服务器之间的数据传送协议。作为应用层协议,HTTP是基于TCP/IP协议来传递数据的(HTML文件、图片、查询结果等),HTTP协议不涉及数据包(Packet)传输,主要规定了客户端和服务器之间的通信格式。

从图上你可以看到,这个过程是:

1) 用户通过浏览器进行了一个操作,比如输入网址并回车,或者是点击链接,接着浏览器获取了这个事件。2) 浏览器向服务端发出TCP连接请求。3) 服务程序接受浏览器的连接请求,并经过TCP三次握手建立连接。4) 浏览器将请求数据打包成一个HTTP协议格式的数据包。5) 浏览器将该数据包推入网络,数据包经过网络传输,最终达到端服务程序。6) 服务端程序拿到这个数据包后,同样以HTTP协议格式解包,获取到客户端的意图。7) 得知客户端意图后进行处理,比如提供静态文件或者调用服务端程序获得动态结果。8) 服务器将响应结果(可能是HTML或者图片等)按照HTTP协议格式打包。9) 服务器将响应数据包推入网络,数据包经过网络传输最终达到到浏览器。10) 浏览器拿到数据包后,以HTTP协议的格式解包,然后解析数据,假设这里的数据是HTML。11) 浏览器将HTML文件展示在页面上。那我们想要探究的Tomcat作为一个HTTP服务器,在这个过程中都做了些什么事情呢?主要是接受连接、解析请求数据、处理请求和发送响应这几个步骤。

2.2 Http服务器请求处理

浏览器发给服务端的是一个HTTP格式的请求,HTTP服务器收到这个请求后,需要调用服 务端程序来处理,所谓的服务端程序就是你写的Java类,一般来说不同的请求需要由不同 的Java类来处理。

1) 图1 , 表示HTTP服务器直接调用具体业务类,它们是紧耦合的。2) 图2,HTTP服务器不直接调用业务类,而是把请求交给容器来处理,容器通过Servlet(色为的)接口调用业务类。因此Servlet(色为的)接口和Servlet(色为的)容器的出现,达到了HTTP服务器与业务类解耦的目的。而Servlet(色为的)接口和Servlet(色为的)容器这一整套规范叫作Servlet(色为的)规范。Tomcat按照Servlet(色为的)规范的要求实现了Servlet(色为的)容器,同时它们也具有HTTP服务器的功能。作为Java程序员,如果我们要实现新的业务功能,只需要实现一个Servlet(色为的),并把它注册到Tomcat(Servlet容器)中,剩下的事情就由Tomcat帮我们处理了。

三. Servlet容器工作流程

为了解耦,HTTP服务器不直接调用Servlet(色为的),而是把请求交给Servlet(色为的)容器来处理,那Servlet(色为的)容器又是怎么工作的呢?当客户请求某个资源时,HTTP服务器会用一个ServletRequest(色为的 为快的)对象把客户的请求信息封装起来,然后调用Servlet(色为的)容器的service(色为的)方法,Servlet(色为的)容器拿到请求后,根据请求的URL和Servlet(色为的)的映射关系,找到相应的Servlet(色为的),如果Servlet(色为的)还没有被加载,就用反射机制创建这个Servlet(色为的),并调用Servlet(色为的)的init(in 奶的)方法来完成初始化,接着调用Servlet(色为的)的service(色为的)方法来处理请求,把ServletResponse(色为的 瑞邦的)对象返回给HTTP服务器,HTTP服务器会把响应发送给客户端。

四Tomcat整体架构

我们知道如果要设计一个系统,首先是要了解需求,我们已经了解了Tomcat要实现两个 核心功能: 1) 处理Socket(少改)连接,负责网络字节流与Request(瑞快死的)和Response(瑞死榜死)对象的转化。 2) 加载和管理Servlet(色为的),以及具体处理Request(瑞快死的)请求。 因此Tomcat设计了两个核心组件连接器(Connector)(可耐的)和容器(Container)(可提热)来分别做这 两件事情。连接器负责对外交流,容器负责内部处理。 五连接器 - Coyote(k有你)

Coyote(k有你) 是Tomcat的连接器框架的名称 , 是Tomcat服务器提供的供客户端访问的外部接口。客户端通过Coyote(k有你)与服务器建立连接、发送请求并接受响应 。Coyote 封装了底层的网络通信(Socket(少改) 请求及响应处理),为Catalina(卡 塔 琳娜)容器提供了统一的接口,使Catalina(卡塔琳娜)容器与具体的请求协议及IO操作方式完全解耦。Coyote(k有你) 将Socket(少改) 输入转换封装为 Request (瑞快死的)对象,交由Catalina(卡 塔 琳娜) 容器进行处理,处理请求完成后, Catalina(卡塔琳娜) 通过Coyote(k有你) 提供的Response(瑞死榜死) 对象将结果写入输出流 。Coyote (k有你)作为独立的模块,只负责具体协议和IO的相关操作, 与Servlet(色为的) 规范实现没有直接关系,因此即便是 Request(瑞快死的) 和 Response(瑞死榜死) 对象也并未实现Servlet(色为的)规范对应的接口, 而是在Catalina 中将他们进一步封装为ServletRequest(色为的 为快的) 和 ServletResponse(色为的 瑞邦的) 。

六.IO模型与协议

在Coyote(k有你)中 , Tomcat支持的多种I/O模型和应用层协议,具体包含哪些IO模型和应用层协议,请看下表:Tomcat 支持的IO模型(自8.5/9.0 版本起,Tomcat 移除了 对 BIO 的支持):北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090IO模型描述NIO 非阻塞I/O,采用Java NIO类库实现。NIO2 异步I/O,采用JDK 7最新的NIO2类库实现。APR采用Apache可移植运行库实现,是C/C++编写的本地库。如果选择该方案,需要单独安装APR库。应用层协议描述HTTP/1.1 这是大部分Web应用采用的访问协议。AJP用于和Web服务器集成(如Apache),以实现对静态资源的优化以及集群部署,当前支持AJP/1.3。HTTP/2HTTP 2.0大幅度的提升了Web性能。下一代HTTP协议 , 自8.5以及9.0版本之后支持。Tomcat 支持的应用层协议 :协议分层 :在 8.0 之前 , Tomcat 默认采用的I/O方式为 BIO , 之后改为 NIO。 无论 NIO、NIO2还是 APR, 在性能方面均优于以往的BIO。 如果采用APR, 甚至可以达到 Apache HTTPServer(色为的) 的影响性能。Tomcat为了实现支持多种I/O模型和应用层协议,一个容器可能对接多个连接器,就好比一个房间有多个门。但是单独的连接器或者容器都不能对外提供服务,需要把它们组装起来才能工作,组装后这个整体叫作Service组件。这里请你注意,Service本身没有做什么重要的事情,只是在连接器和容器外面多包了一层,把它们组装在一起。Tomcat内可能有多个Service(色为的),这样的设计也是出于灵活性的考虑。通过在Tomcat中配置多个Service(色为的),可以实现通过不同的端口号来访问同一台机器上部署的不同应用。

连接器组件 连接器中的各个组件的作用如下:

EndPoint(an保)1) EndPoint(an保) : Coyote(k有你) 通信端点,即通信监听的接口,是具体Socket(少改)接收和发送处理器,是对传输层的抽象,因此EndPoint(Abstract)用来实现TCP/IP协议的。2) Tomcat 并没有EndPoint(an保) 接口,而是提供了一个抽象类AbstractEndpoint (阿的死抓的an保)义了两个内部类:Acceptor和SocketProcessor。Acceptor用于监听Socket连接请求。SocketProcessor用于处理接收到的Socket请求,它实现Runnable接口,在Run方法里调用协议处理组件Processor进行处理。为了提高处理能力,SocketProcessor被提交到线程池来执行。而这个线程池叫作执行器(Executor),我在后面的专栏会详细介绍Tomcat如何扩展原生的Java线程池。Processor(卡死的)Processor : Coyote 协议处理接口 ,如果说EndPoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议,Processor接收来自EndPoint的Socket,读取字节流解析成Tomcat Request和Response对象,并通过Adapter将其提交到容器处理,Processor是对应用层协议的抽象。ProtocolHandler(跑的考 寒的热)

ProtocolHandler: Coyote 协议接口, 通过Endpoint 和 Processor , 实现针对具体协议的处理能力。Tomcat 按照协议和I/O 提供了6个实现类 : AjpNioProtocol ,AjpAprProtocol, AjpNio2Protocol , Http11NioProtocol ,Http11Nio2Protocol ,Http11AprProtocol。我们在配置tomcat/conf/server.xml 时 , 至少要指定具体的ProtocolHandler , 当然也可以指定协议名称 , 如 : HTTP/1.1 ,如果安装了APR,那么将使用Http11AprProtocol , 否则使用 Http11NioProtocol 。Adapter(阿宝的热)由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的Request类来“存放”这些请求信息。ProtocolHandler接口负责解析请求并生成Tomcat Request类。但是这个Request对象不是标准的ServletRequest,也就意味着,不能用TomcatRequest作为参数来调用容器。Tomcat设计者的解决方案是引入CoyoteAdapter,这是适配器模式的经典运用,连接器调用CoyoteAdapter的Sevice方法,传入的是TomcatRequest对象,CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调用容器的Service方法。

七.Catalina(卡塔琳娜) 结构

 Catalina(卡塔琳娜) 的主要组件结构如下:

Catalina(卡塔琳娜)负责解析Tomcat的配置文件 , 以此来创建服务器Server(色为的)组件,并根据命令来对其进行管理Server(色为的)服务器表示整个Catalina Servlet(色为的)容器以及其它组件,负责组装并启动Servlet(色为的)引擎,Tomcat连接器。Server通过实现Lifecycle(饿来的色扣接口,提供了一种优雅的启动和关闭整个系统的方式Service(色为的)服务是Server(色为的)内部的组件,一个Server(色为的)包含多个Service。它将若干个Connector(可耐的)组件绑定到一个Container(可提的)上Connector(可耐的)连接器,处理与客户端的通信,它负责接收客户请求,然后转给相关的容器处理,最后向客户返回响应结果Container(可提的) 容器,负责处理用户的servlet请求,并返回对象给web用户的模块Container(可提的) 结构Tomcat设计了4种容器,分别是Engine、Host、Context和Wrapper。这4种容器不是平行关系,而是父子关系。, Tomcat通过一种分层的架构,使得Servlet容器具有很好的灵活性。各个组件的含义 :Engine(嗯经)表示整个Catalina的Servlet引擎,用来管理多个虚拟站点,一个Service最多只能有一个Engine,但是一个引擎可包含多个HostHost(厚死的)代表一个虚拟主机,或者说一个站点,可以给Tomcat配置多个虚拟主机地址,而一个虚拟主机下可包含多个ContextContext(康text)表示一个Web应用程序, 一个Web应用可包含多个WrapperWrapper (喔报表示一个Servlet,Wrapper 作为容器中的最底层,不能包含子容器我们也可以再通过Tomcat的server.xml配置文件来加深对Tomcat容器的理解。Tomcat采用了组件化的设计,它的构成组件都是可配置的,其中最外层的是Server,其他组件按照一定的格式要求配置在这个顶层容器中。那么,Tomcat是怎么管理这些容器的呢?你会发现这些容器具有父子关系,形成一个树形结构,你可能马上就想到了设计模式中的组合模式。没错,Tomcat就是用组合模式来管理这些容器的。具体实现方法是,所有容器组件都实现了Container接口,因此组合模式可以使得用户对单容器对象和组合容器对象的使用具有一致性。这里单容器对象指的是最底层的Wrapper,组合容器对象指的是上面的Context、Host或者Engine。

八Tomcat 启动流程

 步骤 :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。6) 然后在调用后续组件的初始化操作 。。。加载Tomcat的配置文件,初始化容器组件 ,监听对应的端口号, 准备接受客户端请求Lifecycle由于所有的组件均存在初始化、启动、停止等生命周期方法,拥有生命周期管理的特性, 所以Tomcat在设计的时候, 基于生命周期管理抽象成了一个接口 Lifecycle ,而组件 Server、Service、Container、Executor、Connector 组件 , 都实现了一个生命周期的接口,从而具有了以下生命周期中的核心方法:

1) init():初始化组件  in耐的2) start():启动组件   死导的3) stop():停止组件    死导4) destroy():销毁组件  滴死导

各组件的默认实现

上面我们提到的Server、Service、Engine、Host、Context都是接口, 下图中罗列了这些接口的默认实现类。当前对于 Endpoint组件来说,在Tomcat中没有对应的Endpoint接口, 但是有一个抽象类 AbstractEndpoint ,其下有三个实现类: NioEndpoint、Nio2Endpoint、AprEndpoint , 这三个实现类,分别对应于前面讲解链接器 Coyote时, 提到的链接器支持的三种IO模型:NIO,NIO2,APR , Tomcat8.5版本中,默认采用的是 NioEndpoint(牛的按 跑in的上面我们提到的Server、Service、Engine、Host、Context都是接口, 下图中罗列了这些接口的默认实现类。当前对于 Endpoint组件来说,在Tomcat中没有对应的Endpoint接口, 但是有一个抽象类 AbstractEndpoint ,其下有三个实现类: NioEndpoint、Nio2Endpoint、AprEndpoint , 这三个实现类,分别对应于前面讲解链接器 Coyote时, 提到的链接器支持的三种IO模型:NIO,NIO2,APR , Tomcat8.5版本中,默认采用的是 NioEndpoint。牛的按 跑in的

九Tomcat 请求处理流程

请求流程

设计了这么多层次的容器,Tomcat是怎么确定每一个请求应该由哪个Wrapper(喔爆)容器里的Servlet来处理的呢?答案是,Tomcat是用Mapper(买普组件来完成这个任务的。Mapper组件的功能就是将用户请求的URL定位到一个Servlet,它的工作原理是:Mapper组件里保存了Web应用的配置信息,其实就是容器组件与访问路径的映射关系,比如Host容器里配置的域名、Context容器里的Web应用路径,以及Wrapper容器里Servlet映射的路径,你可以想象这些配置信息就是一个多层次的Map。

当一个请求到来时,Mapper组件通过解析请求URL里的域名和路径,再到自己保存的Map里去查找,就能定位到一个Servlet。请你注意,一个请求URL最后只会定位到一个Wrapper容器,也就是一个Servlet。下面的示意图中 , 就描述了 当用户请求链接 http://www.itcast.cn/bbs/findAll 之后, 是如何找到最终处理业务逻辑的servlet 。那上面这幅图只是描述了根据请求的URL如何查找到需要执行的Servlet , 那么下面我们再来解析一下 , 从Tomcat的设计架构层面来分析Tomcat的请求处理。

步骤如下:1) Connector(可耐的)组件Endpoint(and 跑赢)中的Acceptor监听客户端套接字连接并接收Socket(少改的)。2) 将连接交给线程池Executor(in的热k的)处理,开始执行请求响应任务。3) Processor(跑卡死)组件读取消息报文,解析请求行、请求体、请求头,封装成Request(瑞快死的)对象。4) Mapper(买普)组件根据请求行的URL值和请求头的Host值匹配由哪个Host容器、Context(康text的)容器、Wrapper(我爆)容器处理请求。5) CoyoteAdaptor(可有你按的打死的)组件负责将Connector(可耐的)组件和Engine(嗯经)容器关联起来,把生成的Request(瑞快死的)对象和响应对象Response(瑞死榜死)传递到Engine(嗯经)容器中,调用 Pipeline(拍不按的)。6) Engine(嗯经)容器的管道开始处理,管道中包含若干个Valve、每个Valve负责部分处理逻辑。执行完Valve后会执行基础的 Valve--StandardEngineValve,负责调用Host容器的Pipeline(拍不按的)。7) Host容器的管道开始处理,流程类似,最后执行 Context容器的Pipeline(拍不按的)。8) Context容器的管道开始处理,流程类似,最后执行 Wrapper容器的Pipeline(拍不按的)。9) Wrapper容器的管道开始处理,流程类似,最后执行 Wrapper容器对应的Servlet对象的 处理方法。在Tomcat中定义了Pipeline (拍不按的)和 Valve 两个接口,Pipeline (拍不按的)用于构建责任链, 后者代表责任链上的每个处理器。Pipeline(拍不按的) 中维护了一个基础的Valve,它始终位于Pipeline的末端(最后执行),封装了具体的请求处理和输出响应的过程。当然,我们也可以调用addValve()方法, 为Pipeline (拍不按的)添加其他的Valve, 后添加的Valve 位于基础的Valve之前,并按照添加顺序执行。Pipiline(拍不按的)通过获得首个Valve来启动整合链条的执行 。

十.Jasper

Jasper(接死跑简介

对于基于JSP 的web应用来说,我们可以直接在JSP页面中编写 Java代码,添加第三方的标签库,以及使用EL表达式。但是无论经过何种形式的处理,最终输出到客户端的都是标准的HTML页面(包含js ,css...),并不包含任何的java相关的语法。 也就是说, 我们可以把jsp看做是一种运行在服务端的脚本。 那么服务器是如何将 JSP页面转换为HTML页面的呢?Jasper模块是Tomcat的JSP核心引擎,我们知道JSP本质上是一个Servlet。Tomcat使用Jasper对JSP语法进行解析,生成Servlet并生成Class字节码,用户在进行访问jsp时,会访问Servlet,最终将访问的结果直接响应在浏览器端 。另外,在运行的时候,Jasper还会检测JSP文件是否修改,如果修改,则会重新编译JSP文件。

JSP 编译方式

Tomcat 并不会在启动Web应用的时候自动编译JSP文件, 而是在客户端第一次请求时,才编译需要访问的JSP文件。创建一个web项目, 并编写JSP代码 :<%@ page import="java.text.DateFormat" %><%@ page import="java.text.SimpleDateFormat" %><%@ page import="java.util.Date" %><%@ page contentType="text/html;charset=UTF‐8" language="java" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html><head><title>$Title$</title></head><body><%DateFormat dateFormat = new SimpleDateFormat("yyyy‐MM‐ddHH:mm:ss");String format = dateFormat.format(new Date());%>Hello , Java Server Page 。。。。<br/><%= format %></body></html>

编译过程

Tomcat 在默认的web.xml 中配置了一个org.apache.jasper.servlet.JspServlet,用于处理所有的.jsp 或 .jspx 结尾的请求,该Servlet 实现即是运行时编译的入口。


Tomcat 在默认的web.xml 中配置了一个org.apache.jasper.servlet.JspServlet,用于处理所有的.jsp 或 .jspx 结尾的请求,该Servlet 实现即是运行时编译的入口。

tomcat入门到精通相关推荐

  1. java从入门到精通_想要开始学java?你要的java从入门到精通布列如下!

    java从入门到精通,让我来告诉你! 毫无疑问,java是当下最火的编程语言之一.对于许多未曾涉足计算机编程的领域「小白」来说,深入地掌握java看似是一件十分困难的事.其实,只要掌握了科学的学习方法 ...

  2. Java学习从入门到精通

    Java Learning Path (一).工具篇 一. JDK (Java Development Kit) JDK是整个Java的核心,包括了Java运行环境(Java Runtime Envi ...

  3. java消息头,Java网络编程从入门到精通:HTTP消息头字段

    Java网络编程从入门到精通:HTTP消息头字段 一.通用头字段 1. Connection 这个字段只在HTTP1.1协议中存在.它决定了客户端和服务器进行了一次会话后, 服务器是否立即关闭网络连接 ...

  4. SpringBoot入门到精通_第6篇 _必知必会

    接上一篇:SpringBoot入门到精通_第5篇 _SpringBoot Actuator监控 https://blog.csdn.net/weixin_40816738/article/detail ...

  5. @aspect注解类不生效_Spring Boot从入门到精通(三)常用注解含义及用法分析总结...

    Spring Boot是目前非常流行的框架,而注解是Spring Boot的核心功能,接下来主要说一说Spring Boot常用注解的含义以及部分注解在项目中的使用方法. @RestControlle ...

  6. Java学习从入门到精通[转]

    Java Learning Path (一).工具篇   一. JDK (Java Development Kit) JDK是整个Java的核心,包括了Java运行环境(Java Runtime En ...

  7. 拿来吧你! | 从入门到精通docker ,都在这里了

    Docker 入门到精通 1.DockerFile 介绍 dockerfile 是啥?dockerfile 用来构建 docker 镜像的文件. 具体步骤: 1.编写一个 dockerfile 文件 ...

  8. 排除万难,从入门到精通区块链

    目前越来越多的人已经进入或准备进入区块链领域,过程中不免抱着各样的疑虑和问题.想起自己之前用几年时间,从"略懂"区块链到all in,同样也经历着类似的心路历程,这个领域确实是有一 ...

  9. 真正的Java学习从入门到精通

    一. 工具篇JDK (Java Development Kit) oF[l�bZk0   `WR4j-   JDK 是整个Java的核心,包括了Java运行环境(Java Runtime Envirn ...

最新文章

  1. java模拟浏览器不关闭会话_JSP实现浏览器关闭cookies情况下的会话管理
  2. LeetCode 555. 分割连接字符串
  3. Python工作笔记-使用Py遍历文件夹及其子文件夹内容
  4. python正则表达式匹配字母和下划线_个英文字母、下划线或汉字的正则表达式
  5. 【飞行器】基于matlab多源信息融合算法多旋翼无人机组合导航系统【含Matlab源码 1267期】
  6. 百度编辑器ueditor 的 submit 表单提交
  7. Onenote 安装GEM 插件 失败~修复
  8. 史陶比尔staubli机器人手柄控制器维修操作屏修理
  9. 杰理AC692X系列---关于692x及693x的打开在线调EQ功能(4)
  10. flutter-可拖动悬浮按钮
  11. 工商管理专业知识与实务(初级)【7】
  12. 从键盘输入一个阿拉伯数字,输出对应的财务数字, 用switch。/*零、壹、贰、叁、肆、伍、陆、柒、捌、玖、亿、万、仟、佰、拾。
  13. 电子元器件符号+实物图+命名规则(太全了,绝对收藏)
  14. Android读出Excel报表数据然后导出写入到SQLite数据库
  15. 深空通信相关资料——以火星为例
  16. mcafee自定义规则在系统中表示
  17. SAA 心理素质差差的
  18. POJ 3009 Curling 2.0 {深度优先搜索}
  19. 你的下一台电脑又何必是电脑?【电子爱穿搭】
  20. List数组去重的几种方法

热门文章

  1. 计算机打印机设置,网口打印机设置教程(新)
  2. Javascript:ES6-ES11(2)
  3. vivado cordic IP学习记录
  4. python爬取豆瓣排行榜电影数据(含GUI界面版)
  5. 万年历编写一年c语言思,万年历C语言
  6. 云服务器 exe文件打不开,详细教您exe文件打不开的解决方法
  7. Flexsim案例分析2
  8. [转]AES加密算法及java代码实现
  9. Office文档背景变成黑色 - 解决方案
  10. 寻vmos虚拟大师提取os 安装的办法