文档章节

死磕Tomcat系列(1)——整体架构

 不学无数的程序员
发布于 06/12 11:47
字数 1804
阅读 270
收藏 9

死磕Tomcat系列(1)——整体架构

在许多的高端开发的岗位中都会或多或少有要求面试人员要研究过一些常用中间件源码。这是因为一切的秘密都是藏在源码中,阅读源码能够让我们对框架或者中间件的理解更加深刻,而我们也能够在源码的研究中获得其中一些优秀的设计方式。而我们的中间件和源码那么多,我们该从何入手呢?其实大部分的中间件或者框架都有一些共性的部分,例如网络编程、多线程、反射和类加载等技术。所以深入研究透了一两个中间价的话,那么再回过头来看其他的中间件,那么就会很容易理解它里面所用的技术以及原理。而作为一个老牌的WEB端框架Tomcat,无论是其整体的架构设计,还是其内在的一些技术灵活应用,都值得我们一看。

在学习框架的时候,我一般都是对这个框架有一个整体的认识。知道它整体是如何运行的,然后再深入其中某部分进行研究,这样会事半功倍。

整体架构

我们想要了解一个框架,首先要了解它是干什么的,Tomcat我们都知道,是用于处理连接过来的Socket请求的。那么Tomcat就会有两个功能:

  • 对外处理连接,将收到的字节流转化为自己想要的Request和Response对象
  • 对内处理Servlet,将对应的Request请求分发到相应的Servlet中

那么我们整体的骨架就出来了,Tomcat其实就分为两大部分,一部分是连接器(Connnector)处理对外连接和容器(Container)管理对内的Servelet。大体的关系图如下

最外层的大框就是代表一个Tomcat服务,一个Tomcat服务可以对应多个Service。每个Service都有连接器和容器。这些对应的关系我们也可以打开在Tomcat目录配置文件中server.xml中看出来。

<Server port="8006" shutdown="SHUTDOWN">
  <Service name="Catalina">

    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <Connector port="8010" protocol="AJP/1.3" redirectPort="8443" />

    <Engine name="Catalina" defaultHost="localhost">

      <Realm className="org.apache.catalina.realm.LockOutRealm">
       
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
       
      </Host>
    </Engine>
  </Service>
</Server>

这里我将其中配置文件中删除了一些内容精简了一下,这里我们可以看到连接器其实就是Connector ,一个Service中可以有多个连接器,容器其实对应的就是Engine

Tomcat的整体架构简单来说就是这样的对应关系。接下来我们简单的介绍连接器的整体架构和容器的整体架构。

连接器

我们可以看到上图中连接器传给容器的是ServletRequest对象,而容器传给连接器的是ServletResponse对象,这些在网络传输过程中是肯定不行的,因为网络传输中传送的字节流。所以连接器的功能需求我们大概能总结出来以下几点。

  • Socket连接
  • 读取请求网络中的字节流
  • 根据相应的协议(Http/AJP)解析字节流,生成统一的Tomcat Requestt对象
  • Tomcat Reques传给容器
  • 容器返回Tomcat Response对象
  • Tomcat Response对象转换为字节流
  • 将字节流返回给客户端

其实上面的细分都能总结为以下的三点

  • 网络通信
  • 应用层协议的解析
  • Tomcat的Request/ResponseServletRequest/ServletResponse对象的转化

而在Tomcat中它也用了三个类来实现上面的三个功能,分别对应如下

  • EndPoint
  • Processor
  • Adapter

用图表示他们的关系的话就是这样

容器

容器,顾名思义就是装东西的器具,那么这个Tomcat容器是装什么的呢?其实主要的就是装了Servlet的。那么容器是如何设计的呢?Tomcat的容器设计其实是用了组合设计模式(不了解组合设计模式的可以看我之前的文章不学无数——组合模式)。其实从Server.xml中我们也能看到其关系了。

  <Engine name="Catalina" defaultHost="localhost">
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

      </Host>
    </Engine>

在这里面我们只能看到容器中的两个模块,一个是顶层模块Engine,另一个是Host,其实还有两个模块,一个是Context对应的是我们webapp里面的每个应用文件夹,每个文件夹就是对应一个Context,还有一个模块Wrapper对应的是我们Context中的所有servlet,Wrapper管理了访问关系与具体的Servlet的对应。图表示就是下面这样。

Tomcat中容器所有模块都实现了Container接口,而组合模式的意义就是使得用户对于单个对象和组合对象的使用具有一致性,即无论添加多少个Context其使用就是为了找到其下面的Servlet,而无论添加多少个Host也是为了找个下面的Servlet。而在容器中设计了这么多的模块,一个请求过来Tomcat如何找到对应的Servlet进行处理呢?

请求如何定位

我们就举个最简单的例子,我们本机应用上启动了一个Tomcat,webapp下有我们部署的一个应用buxuewushu。我们在浏览器上输入http://localhost:8080/buxuewushu/add.do是如何找到对应Servlet进行处理呢?

在我们启动Tomcat的时候,连接器就会进行初始化监听所配置的端口号,这里我们配置的是8080端口对应的协议是HTTP。

  • 请求发送到本机的8080端口,被在那里监听的HTTP/1.1的连接器Connector获得
  • 连接器Connector将字节流转换为容器所需要的ServletRequest对象给同级Service下的容器模块Engine进行处理
  • Engine获得地址http://localhost:8080/buxuewushu/add。匹配他下面的Host主机
  • 匹配到名为localhost的Host(就算此时请求为具体的ip,没有配置相应的Host,也会交给名为localhost的Host进行处理,因为他是默认的主机)
  • Host匹配到路径为/buxuewushu的Context,即在webapp下面找到相应的文件夹
  • Context匹配到URL规则为*.do的servlet,对应为某个Servlet类
  • 调用其doGet或者doPost方法
  • Servlet执行完以后将对象返回给Context
  • Context返回给Host
  • Host返回给Engine
  • Engine返回给连接器Connector
  • 连接器Connector将对象解析为字节流发送给客户端

往期关于Tomcat的文章

参考

© 著作权归作者所有

不学无数的程序员

粉丝 38
博文 46
码字总数 86962
作品 0
私信 提问
死磕Tomcat系列(5)——容器

死磕Tomcat系列(5)——容器 回顾 在死磕Tomcat系列(1)——整体架构中我们简单介绍了容器的概念,并且说了在容器中所有子容器的父接口是。在死磕Tomcat系列(2)——EndPoint源码解析中,我们知...

不学无数的程序员
07/08
50
0
死磕Tomcat系列(6)——Tomcat如何做到热加载和热部署的

死磕Tomcat系列(6)——Tomcat如何做到热加载和热部署的 热部署就是在服务器运行时重新部署项目,热加载即在在运行时重新加载class,从而升级应用。 通常情况下在开发环境中我们使用的是热加载...

不学无数的程序员
07/12
1K
4
死磕Tomcat系列(3)——Tomcat如何做到一键式启停的

死磕Tomcat系列(3)——Tomcat如何做到一键式启停的 在没有SpringBoot内嵌有Tomcat之前,我们都是将项目打为War包放在Tomcat的webapp目录下面,然后如果是Linux系统,运行命令、如果是Windows...

不学无数的程序员
06/26
56
0
死磕Tomcat系列(4)——Tomcat中的类加载器

死磕Tomcat系列(4)——Tomcat中的类加载器 在学习Tomcat中的类加载器,并且Tomcat为什么要实现自己的类加载器打破双亲委派模型原因之前,我们首先需要知道Java中定义的类加载器是什么,双亲委...

不学无数的程序员
07/05
60
0
死磕 java同步系列之CyclicBarrier源码解析——有图有真相

问题 (1)CyclicBarrier是什么? (2)CyclicBarrier具有什么特性? (3)CyclicBarrier与CountDownLatch的对比? 简介 CyclicBarrier,回环栅栏,它会阻塞一组线程直到这些线程同时达到某个...

彤哥读源码
06/28
126
0

没有更多内容

加载失败,请刷新页面

加载更多

从零基础到拿到网易Java实习offer,我做对了哪些事

作为一个非科班小白,我在读研期间基本是自学Java,从一开始几乎零基础,只有一点点数据结构和Java方面的基础,到最终获得网易游戏的Java实习offer,我大概用了半年左右的时间。本文将会讲到...

Java技术江湖
昨天
4
0
程序性能checklist

程序性能checklist

Moks角木
昨天
6
0
VUE 计算属性

本文转载于:专业的前端网站▶VUE 计算属性 1、示例代码 <!DOCTYPE html><html lang="zh"> <head> <meta charset="UTF-8" /> <title>vue示例</title> </hea......

前端老手
昨天
5
0
快速搭建LNMT平台和环境部署 Tomcat详解

Tomcat部署的基本概念 1. CATALINA_HOME与CATALINA_BASE分别指什么?     CATALINA_HOME指的是Tomcat的安装目录     bin:\\Tomcat一些脚本存放目录,比如启动脚本startup.bat/start...

网络小虾米
昨天
6
0
float浮动

float浮动 float浮动概念及原理: 文档流:文档流是文档中可显示对象在排列时所占用的位置。 加浮动的元素,会脱离文档流,会沿父容器靠左或靠右排列,如果之前已经有浮动的元素,会挨着浮动...

studywin
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部