Web概念
-
软件架构
- C/S: 客户端/服务器端 ‐‐‐‐‐‐‐‐‐‐‐‐> QQ , 360 …
- B/S: 浏览器/服务器端 ‐‐‐‐‐‐‐‐‐‐‐‐> 京东, 网易 , 淘宝 , 传智播客官网
-
资源分类
-
静态资源: 所有用户访问后,得到的结果都是一样的,称为静态资源。静态资源可以直接被浏览器解
析。
-
如: html,css,JavaScript,jpg
-
-
动态资源: 每个用户访问相同资源后,得到的结果可能不一样 , 称为动态资源。
- 动态资源被访问后,需要先转换为静态资源,再返回给浏览器,通过浏览器进行解析。
- 如:servlet/jsp,php,asp…
-
网络通信三要素
-
IP:电子设备(计算机)在网络中的唯一标识。
-
端口:应用程序在计算机中的唯一标识。 0~65536
-
传输协议:规定了数据传输的规则
- 基础协议:
- tcp : 安全协议,三次握手。 速度稍慢
- udp:不安全协议。 速度快
- 基础协议:
-
URL
- 在互联网中每个资源(html、css、js、img、png、video)都有一个唯一地址去标识该资源。
- URL全称Uniform Resource Locator(统一资源定位符)
- URL:通常是由 ip地址、端口号、资源名称、协议名、项目名等组成。
HTTP
- HTTP全称 Hypertext Transefer Protocol 超文本传输协议。
- 浏览器和服务器之间进行数据交互的协议。
常见的Web服务器
Tomcat安装
前提条件:安装好了JDK(因为jsp转换成servlet后需要编译,所以需要jdk )
具体:tomcat安装前为什么要安装jdk?
Tomcat点击查看:https://blog.csdn.net/qq_40881680/article/details/83582484
Tomcat启动和停止
启动
双击 bin/startup.bat 文件 ;
停止
双击 bin/shutdown.bat 文件 ;
访问
http://localhost:8080
默认是8080端口
Tomcat源码部署运行
视频点击:https://www.bilibili.com/video/av68043130?p=5
Tomcat 架构
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服务器,在这个过程中都做了些什么事情呢?主要是接受连接、解析请求数据、处理请求和发送响应这几个步骤。
Http服务器请求处理
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方法来完成初始化,接着调用Servlet
的service方法来处理请求,把ServletResponse对象返回给HTTP服务器,HTTP服务器会把响应发送给客户端。
Tomcat整体架构
我们知道如果要设计一个系统,首先是要了解需求,我们已经了解了Tomcat要实现两个核心功能:
1) 处理Socket连接,负责网络字节流与Request和Response对象的转化。
2) 加载和管理Servlet,以及具体处理Request请求。
因此Tomcat设计了两个核心组件连接器(Connector)和容器(Container)来分别做这两件事情。连接器负责对
外交流,容器负责内部处理。
- 一个容器可以对应多个连接器
- 连接器和容器不能单独对外提供服务
- 容器和连接器组成的service才能对外提供服务
连接器–Coyote
架构介绍
Coyote 是Tomcat的连接器框架的名称 , 是Tomcat服务器提供的供客户端访问的外部接口。客户端通过Coyote与
服务器建立连接、发送请求并接受响应 。
Coyote 封装了底层的网络通信(Socket 请求及响应处理),为Catalina 容器提供了统一的接口,使Catalina 容器
与具体的请求协议及IO操作方式完全解耦。Coyote 将Socket 输入转换封装为 Request 对象,交由Catalina 容器
进行处理,处理请求完成后, Catalina 通过Coyote 提供的Response 对象将结果写入输出流 。
Coyote 作为独立的模块,只负责具体协议和IO的相关操作, 与Servlet 规范实现没有直接关系,因此即便是
Request 和 Response 对象也并未实现Servlet规范对应的接口, 而是在Catalina 中将他们进一步封装为
ServletRequest 和 ServletResponse 。
IO模型与协议
Tomcat为了实现支持多种I/O模型和应用层协议,一个容器可能对接多个连接器,就好比一个房间有多个门。但是
单独的连接器或者容器都不能对外提供服务,需要把它们组装起来才能工作,组装后这个整体叫作Service组件。
这里请你注意,Service本身没有做什么重要的事情,只是在连接器和容器外面多包了一层,把它们组装在一起。
Tomcat内可能有多个Service,这样的设计也是出于灵活性的考虑。通过在Tomcat中配置多个Service,可以实现
通过不同的端口号来访问同一台机器上部署的不同应用。
连接器组件
容器–Catalina
Catalina地位
Tomcat是一个由一系列可配置的组件构成的Web容器,而Catalina是Tomcat的servlet容器。
Catalina 是Servlet 容器实现,包含了之前讲到的所有的容器组件,以及后续章节涉及到的安全、会话、集群、管
理等Servlet 容器架构的各个方面。它通过松耦合的方式集成Coyote,以完成按照请求协议进行数据读写。同时,
它还包括我们的启动入口、Shell程序等。
Tomcat 本质上就是一款 Servlet 容器, 因此Catalina 才是 Tomcat 的核心 , 其他模块都是为Catalina 提供支撑
的。 比如 : 通过Coyote 模块提供链接通信,Jasper 模块提供JSP引擎,Naming 提供JNDI 服务,Juli 提供日志服
务。
Catalina结构
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用户的模块 |
Container 结构
Tomcat设计了4种容器,分别是Engine、Host、Context和Wrapper。这4种容器不是平行关系,而是父子关系。
Tomcat通过一种分层的架构,使得Servlet容器具有很好的灵活性。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BQcxwxPN-1667727239384)(file:///C:/Users/15991/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg)]
各个组件的含义 :
详细补充: Tomcat系统架----容器
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的配置文件,初始化容器组件 ,监听对应的端口号, 准备接受客户端请求
源码解析参考文章Tomcat核心原理解析_自然醒。的博客-CSDN博客
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 。
请求流程源码解析
在前面所讲解的Tomcat的整体架构中,我们发现Tomcat中的各个组件各司其职,组件之间松耦合,确保了整体架
构的可伸缩性和可拓展性,那么在组件内部,如何增强组件的灵活性和拓展性呢? 在Tomcat中,每个Container
组件采用责任链模式来完成具体的请求处理。
在Tomcat中定义了Pipeline 和 Valve 两个接口,Pipeline 用于构建责任链, 后者代表责任链上的每个处理器。
Pipeline 中维护了一个基础的Valve,它始终位于Pipeline的末端(最后执行),封装了具体的请求处理和输出响
应的过程。当然,我们也可以调用addValve()方法, 为Pipeline 添加其他的Valve, 后添加的Valve 位于基础的
Valve之前,并按照添加顺序执行。Pipiline通过获得首个Valve来启动整合链条的执行 。
Jasper
Jasper 简介
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>
JspServlet 处理流程图:
编译结果
如果在 tomcat/conf/web.xml 中配置了参数scratchdir , 则jsp编译后的结果,就会存储在该目录下 。