tomcat(1)基础与架构

一 web概念

资源分类

  1. 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源。静态资源可以直接被浏览器解析。
    “如: html,css,JavaScript,jpg
  2. 动态资源:每个用户访问相同资源后,得到的结果可能不- -样, 称为动态资源。动态资源被访问后,需要先转换为静态资源,再返回给浏览器,通过浏览器进行解析。如: servlet/jsp,php,asp… .

web服务器

概念

  • 服务器:安装了服务器软件的计算机
  • 服务器软件:接收用户的请求,处理请求,做出响应
  • web服务器软件:接收用户的请求,处理请求,做出响应。在web服务器软件中,可以部署web项目,让用户通过浏览器来访问这些项目

常见web服务器软件

  • webLogic : oracle公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
  • webSphere : IBM公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
  • JBosS : JB0sS公司的,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
  • Tomcat : Apache基金组织,中小型的JavaEE服务器,仅仅支持少量的JavaEe规范servlet/jsp.开源的,免费的。

二 tomcat简介

下载

本文基于tomcat8.5版本
下载地址:https://tomcat.apache.org/download-80.cgi

目录结构

在这里插入图片描述
在这里插入图片描述

源码环境

下载:
在这里插入图片描述

具体参考https://www.cnblogs.com/grasp/p/10061577.html

HTTP原理

http是基于TCP/IP,只是定义了浏览器和服务器端交互的格式在这里插入图片描述
在这里插入图片描述

三 Tomcat整体架构

Http服务器请求处理

浏览器发给服务端的是一个HTTP格式的请求 , HTTP服务器收到这个请求后,需要调用服务端程序来处理,所谓的服务端程序就是你写的Java类,一般来说不同的请求需要由不同的Java类来处理。
有两种方案来实现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容器又是怎么工作的呢?
当客户请求某个资源时,

  1. HTTP服务器会用一个servletRequest对象把客户的请求信息封装起来 ,然后调用servlet容器的service方
  2. servlet容器拿到请求后,根据请求的URL和servle t的映射关系,找到相应的Servlet
  3. 如果servlet还没有被加载,就用反射机制创建这个servlet ,并调用Servlet的init方法来完成初始化,接着调用servlet的service方法来处理请求,
  4. 把servletResponse对象返回给HTTP服务器, HTTP服务器会把响应发送给客户端。

在这里插入图片描述

整体架构

我们知道如果要设计一个系统,首先是要了解需求,我们已经了解了Tomcat要实现两个核心功能:

  1. 处理socket连接 ,负责网络字节流与Request和Response对象的转化。
  2. 加载和管理servlet ,以及具体处理Request请求。

因此Tomcat设计了两个核心组件连接器( Connector )和容器( Container )来分别做这两件事情。连接器负责对外交流,容器负责内部处理。

在这里插入图片描述

四 连接器- Coyote

架构介绍

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

IO模型与协议

在coyote中, Tomcat支持的多种I/O模型和应用层协议,具体包含哪些IO模型和应用层协议,请看下表:
在这里插入图片描述
协议分层
在这里插入图片描述

Service组件

Tomcat为了实现支持多种I/O模型和应用层协议, 一个容器可能对接多个连接器,就好比一个房间有多个门。但是单独的连接器或者容器都不能对外提供服务,需要把它们组装起来才能工作,组装后这个整体叫作service组件。这里请你注意, service本身没有做什么重要的事情,只是在连接器和容器外面多包了一层,把它们组装在一起。
Tomcat内可能有多个service ,这样的设计也是出于灵活性的考虑。通过在Tomcat中配置多个service ,可以实现通过不同的端口号来访问同一台机器上部署的不同应用。

coyote组件和谁对接

在这里插入图片描述
连接器中的各个组件的作用如下:

EndPoint

  1. EndPoint : Coyote通信端点,即通信监听的接口,是具体socket接收和发送处理器,是对传输层的抽象,因此EndPoint用来实现TCP/ IP协议的。(抽象逻辑)
  2. Tomcat并没有EndPoint接口,而是提供了一个抽象类AbstractEndpoint , 里面定义了两个内部类: 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对象,并通过Adapte r将其提交到容器处理,Processor是对应用层协议的抽象

五 servlet容器-catalina

Tomcat是一个由一系列可配置的组件构成的web容器,而Catalina是Tomcat的servlet容器。(一共就两个主要部件,核心当然是servlet容器)
Catalina是servlet容器实现,包含了之前讲到的所有的容器组件,以及后续章节涉及到的安全、会话、集群、管理等servlet容器架构的各个方面。它通过松耦合的方式集成coyote ,以完成按照请求协议进行数据读写。同时,它还包括我们的启动入口、Shell程序等。

地位

tomcat的模块分层图:(tomcat除了servlet容器和连接器外还有一些比较不那么重要的组件)
在这里插入图片描述

catalina结构

在这里插入图片描述
在这里插入图片描述
上图个人理解

  1. catalina是servlet容器,在tomcat启动时读取配置文件,创建了server【参考:初探Tomcat源码 (4) —— Catalina容器结构】(那这里的connector就是前面的coyote)。注意看图:catalina并不是包括了server。catalina管理服务器
  2. 而这个server呢?是一个逻辑上的概念:表示整个服务器,包含了servlet容器、连接器等等所有tomcat组件。
  3. servlet内部可以有多个service(服务)。一组service有至少一个连接器和一个servlet容器组成(前面有提过)
  4. contain是一个抽象的概念,在我看来就是代表着servlet容器。而catalina就是servlet容器,所以本质就是:
    Catalina具有servlet容器的功能,他负责tomcat的启动,协调个组件的关系。然后连接器拿到请求,也是交给他处理。
    在这里插入图片描述

Tomcat是怎么管理这些容器的呢

你会发现这些容器具有父子关系,形成-一个树形结构,你可能马上就想到了设计模式中的组合模式。没错,Tomcat就是用组合模式来管理这些容器的。具体实现方法是,所有容器组件都实现了Container接口,因此组合模式可以使得用户对单容器对象和组合容器对象的使用具有一致性。 这里单容器对象指的是最底层的wrapper 、组合容器对象指的是上面的Context、Host或者Engine。.

在这里插入图片描述

六 启动流程

流程

在这里插入图片描述
总结:加载Tomcat的配置文件| ,初始化容器组件, 监听对应的端口号,准备接受客户端请求 。

lifecycle

在这里插入图片描述

默认实现

在这里插入图片描述
在这里插入图片描述

七 请求处理流程

在这里插入图片描述
在这里插入图片描述

时序图

在这里插入图片描述
步骤如下:

  1. Connector组件Endpoint中的Acceptor监听客户端套接字连接并接收Socket。
  2. 将连接交给线程池Executor处理,开始执行请求响应任务。
  3. Processor组件读取消息报文,解析请求行、请求体、请求头,封装成Request对象
  4. Mapper组件根据请求行的URL值和请求头的Host值匹配由哪个Host容器、Context容器、 Wrapper容器处理请求。
  5. CoyoteAdaptor组件负责将Connector组件和Engine容器关联起来 ,把生成的Request对象和响应对象Response传递到Engine容器(就一个,不用选)中,调用Bipeline。
  6. Engine容器的管道开始处理 ,管道中包含若干个valve(阀)、每个valve负责部分处理逻辑。执行完Valve后会执行基础的Valve---StandardEngineValve ,负责调用Host容器的Pipeline。
  7. Host容器的管道开始处理,流程类似,最后执行Context容器的Pipeline。
  8. Context容器的管道开始处理,流程类似,最后执行wrapper容器的Pipeline。
  9. wrapper容器的管道开始处理 ,流程类似,最后执行wrapper容器对应的servlet对象的处理方法

源码流程图

在这里插入图片描述
在前面所讲解的Tomcat的整体架构中,我们发现Tomcat中的各个组件各司其职,组件之间松耦合,确保了整体架构的可伸缩性和可拓展性,那么在组件内部,如何增强组件的灵活性和拓展性呢?
在Tomcat中 ,每个Container组件采用责任链模式来完成具体的请求处理。在Tomcat中定义了Pipeline和Valve两个接口

  • Pipeline用于构建责任链
  • Valve代表责任链上的每个处理器

Pipeline 中维护了一个基础的valve,它始终位于pipeline的末端(最后执行), 封装了具体的请求处理和输出响应的过程。当然,我们也可以调用addValve ()方法,为Pipeline 添加其他的valve,后添加的valve 位于基础的valve之前,并按照添加顺序执行。Pipiline通过获得首个Valve来启动整合链条的执行。

源码跳过了,不然事倍功半!

参考

  1. java进阶教程Tomcat核心原理解析
发布了107 篇原创文章 · 获赞 1 · 访问量 3955

猜你喜欢

转载自blog.csdn.net/m0_38060977/article/details/104100839
今日推荐