本章节为介绍如何安装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 组件,都实现了一个生命周期的接口,从而具有了以下生命周期中的核心方法:

  1. init():初始化组件
  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。

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基础知识与运行原理的更多相关文章

  1. php基础知识(语法与原理)

    一.php简介 PHP超文本预处理器.是嵌入HTML文件中的服务器脚本程序. PHP代码标记:<?php …. ?> PHP文件的扩展名:.php PHP文件的执行:必须从域名开始访问 P ...

  2. tomcat 基础知识学习

    1: 直接将web项目文件件拷贝到webapps 目录中,Tomcat的Webapps目录是Tomcat默认的应用目录,当服务器启动时,会加载所有这个目录下的应用,所以可以将JSP程序打包成一个 wa ...

  3. Tomcat基础知识

    介绍Tomcat之前先介绍下Java相关的知识. 各常见组件: 1.服务器(server):Tomcat的一个实例,通常一个JVM只能包含一个Tomcat实例:因此,一台物理服务器上可以在启动多个JV ...

  4. 【基础知识】CPU原理之减法、乘法和除法

    中介绍了布尔逻辑.数学和电路的关系,我们也得到了与门.或门.非门.或非门.与非门.异或门等门电路以及一个加法器,并且了解了计算机是如何做加法的,这篇文章介绍一下计算机是如何做减法以及乘除法的. 0x0 ...

  5. FPGA基础知识了解

    FPGA学习的一些误区 FPGA入门必看资源 FPGA百度百科 FPGA基础知识及其工作原理 高端设计工具为少有甚是没有硬件设计技术的工程师和科学家提供现场可编程门阵列(FPGA).无论你使用图形化设 ...

  6. Js基础知识(四) - js运行原理与机制

    js运行机制 本章了解一下js的运行原理,了解了js的运行原理才能写出更优美的代码,提高运行效率,还能解决开发中遇到的不理解的问题. 进程与线程 进程是cpu资源分配的最小单位,进程可以包含多个线程. ...

  7. Web自动化必会知识:「Web基础、元素定位、元素操作、Selenium运行原理、项目实战+框架」

    1.web 基础-html.dom 对象.js 基本语法 Dom 对象里面涉及元素定位以及对元素的修改.因为对元素操作当中涉及的一些 js 操作,js 基本语法要会用.得要掌握前端的基本用法.为什么要 ...

  8. Java基础知识强化之多线程笔记05:Java程序运行原理 和 JVM的启动是多线程的吗

    1. Java程序运行原理:     Java 命令会启动Java 虚拟机,启动 JVM,等于启动了一个应用程序,也就是启动了一个进程.该进程会自动启动一个 “主线程” ,然后主线程去调用某个类的 m ...

  9. 【WEB】Tomcat基础使用知识

    由于当前项目性质原因,从开始到现在使用的WEB服务器都是WAS,而Tomcat的基础知识也慢慢地被遗忘.由于种种原因,让我参与到了另外一个全新的项目,使用的是Tomcat6.X,所以复习是必须的,而写 ...

  10. Java基础—Java运行原理

    Java程序运行原理 在Java中引入了虚拟机(JVM,Java Virtual Machine)的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器.虚拟机在任何平台上都提供给编译程序一个的共同 ...

随机推荐

  1. Ubuntu/Linux系统中的multi-user.target

    相关: https://www.cnblogs.com/devilmaycry812839668/p/17999041 multi-user.target 是 Linux 系统中 systemd 的一 ...

  2. 制约国产深度学习框架发展的根本原因 —— AI芯片的无法自主生产或量产

    秉着没事就胡言乱语的宗旨,这里在接着胡说八道一下. 国外的深度学习框架如TensorFlow.pytorch.Jax打的如火如荼,按照以往惯例我们是不应该去做自主研发软件系统的,毕竟硬件不在掌握之下, ...

  3. Ubuntu18.04环境下安装网络代理软件 proxychains

    安装: 网络代理软件proxychains安装: sudo apt-get install proxychains 为保证使用 proxychains 时 sudo proxychains 时可以实现 ...

  4. git 如何删除一个文件名为nul的文件

    前提 当我发现存在一个nul的文件,手动删除/移动它,都会提示ms-dos功能无效或文件过大.想一想这个nul应该是某个保留字,所以普通的方式不能删除 解决方案 https://stackoverfl ...

  5. 【故障排查】10分钟解决Quartz重复调度的疑难杂症

    我司使用Apache DolphinScheduler作为调度框架很久了,感兴趣的小伙伴可以看看这些干货文章: 因为之前监控到会出现重复的调度的问题,所以此文记录排查重复调度问题的全过程,希望对社区其 ...

  6. 在lcd屏幕上的任意位置显示任意大小的图片

    /************************************************* * * file name:ShowBmp2.c * author :momolyl@126.co ...

  7. 017.Kubernetes二进制集群扩容worker

    一 前置准备 1.1 互信配置 为了更方便远程分发文件和执行命令,本实验配置master节点到其它节点的 ssh 信任关系. 1 [root@master01 ~]# ssh-copy-id -i ~ ...

  8. SMU Spring 2023 Contest Round 2(待补

    M. Different Billing #include <map> #include <set> #include <cmath> #include <q ...

  9. 使用 onNuxtReady 进行异步初始化

    title: 使用 onNuxtReady 进行异步初始化 date: 2024/8/16 updated: 2024/8/16 author: cmdragon excerpt: 摘要:本文详细介绍 ...

  10. 软件开发工程师,几款常用的APP,你用过几款?最后一个测试网络必备

    作为一名程序员,手机里一定有几个常用的app,下面给大家推荐几款. 1. CSDN 国内最大编程论坛:虽然有多少人吐槽现在使用csdn就像屎里淘金, 但是不得不承认他仍然是大家搜索技术资料.问题的首选 ...