Tomcat系列
1-系统架构与原理剖析
文章目录
前言
作为一个后端开发,日常工作中几乎无时无刻不在使用Tomcat,但是也几乎只停留在使用容器上,接下来对Tomcat进行一个深入的学习
一、浏览器访问服务器的流程
b/s(浏览器/服务器)模式 浏览器也就是客户端(发送http请求) ———> 服务器端 这里我们回顾下浏览器访问服务器的流程,也就是http请求的流程 如下图,需要强调的是:http请求只是定义了数据的组织格式,也就是通信格式,只是一个应用层协议,底层的数据传输依靠的依旧是TCP/IP协议
二、Tomcat 系统总体架构
1.Tomcat是什么?
要回答这个问题我们先看一下Tomcat请求处理的大致过程
我们在使用浏览器访问或者请求某一个网站时,浏览器会向服务器发送http请求,也就是远程接收请求的是http服务器,http服务器在接受到请求以后,会调用具体的处理程序来处理,所以Tomcat是一个http服务器 但是如果Tomcat作为Http服务器直接调用处理类完成业务的处理的话就说明Tomcat和业务类完全耦合在了一起,那这个问题怎么解决呢? 实际上,在Http服务器接收到请求以后会把请求交给Servlet服务器进行处理,由Servlet容器调用Servlet接口完成业务处理(Servlet规范),而Tomcat按照Servlet规范实现了Servlet容器,同时又具备Http服务器的功能,所以Tomcat有两个身份: Http服务器+Servlet服务器
所以Http只是和浏览器进行一个交互,具体的业务处理就交给了Servlet容器,完成了解耦
2.Tomcat Servlet容器处理流程
当用户请求某一个URL资源的时候,Tomcat Servlet容器的实际处理流程如下 1)HTTP服务器会把请求信息(原生的Request对象)使用ServletRequest对象封装起来 2)HTTP服务器带着ServletRequest对象请求Servlet服务器 3)Servlet服务器接收到请求后,根据URL和Servlet的映射关系,找到对应的Servlet 4)如果对应的Servlet没有找到(没有加载),则使用反射实例化对应的Servlet,并调用init方法完成初始化 5)执行对应的Servlet的对应service方法处理请求,并把请求结果封装到ServletResponse对象中 6)Servlet服务器将ServletResponse对象返回给Http服务器,HTTP服务器将ServletResponse对象装换成原生的Response对象发送给客户端
如下图所示
3.Tomcat 系统总体架构
通过上面的两部分学习,我们知道Tomcat有两个重要的功能需要完成 1)需要和客户端浏览器进行交互,进行socket通信,将字节流和Request/Response等对象进行转换,即Http服务器功能 2)使用Servlet容器处理业务逻辑,也就是Servlet容器功能
但是这个是从角色的角度将Tomcat分成了两个角色:Http服务器和Servlet容器两个角色 但是从设计的角度来说的话:Tomcat设计的是两个核心组件连接器组件(Connector)和容器组件(Container)两个组件来完成两大核心功能的 连接器组件,负责对外交流:处理socket链接,负责网络字节流与Request和Response对象的转化 容器组件,负责内部处理:加载和管理Servlet,以及具体处理Resuest请求
三、Tomcat 连接器组件 Coyote
1.Coyote简介
Coyote是Tomcat中连接器的组件名称是对外的接口。 客户端通过Coyote与服务器建立连接、发送请求并接收响应 他的作用如下: 1)Coyote封装了底层的网络通信(Socket请求及响应的处理) 2)Coyote是Catalina容器(容器组件后边讲)与具体请求的协议及IO操作方式完全解耦 3)Coyote将Socket输入转换封装为Request对象,进一步分装后交由Catalina容器进行处理,处理请求完成后,Catalina容器通过Coyote提供的Response对象将结果写入输出流 4)Coyote负责的是具体协议(应用层)和IO(传输层)相关内容
2.Tomcat Coyote支持的IO模型和协议
Tomcat支持多种应用层协议和I/O模型,如下: 这里提一下:在tomcat8.0之前,还支持BIO(同步阻塞IO),无论 NIO、NIO2还是APR, 在性能方面均优于以往的BIO。 如果采用APR, 甚至可以达到 Apache HTTP Server 的影响性能(采用APR的话需要独立安装APR的库) 目前新版本的Tomcat默认的IO模型是NIO,默认的协议是HTTP/1.1
3.Coyote的内部组件及流程
1)EndPoint 是 Coyote 通信端点,即通信监听的接口,是具体Socket接收和发送处理器,是对传输层的抽象,因此EndPoint用来实现TCP/IP协议的 2)Processor 是Coyote 协议处理接口 ,如果说EndPoint是用来实现TCP/IP协议的,那么Processor用来实现HTTP协议,Processor接收来自EndPoint的 Socket,读取字节流解析成Tomcat Request和Response对象,并通过 Adapter将其提交到容器处理,Processor是对应用层协议的抽象 3)ProtocolHandler (相当于EndPoint和Processor的组合组件) Coyote 协议接口, 通过Endpoint 和 Processor 实现针对具体协议的处理能力。Tomcat 按照协议和I/O 提供了6个实现类 : AjpNioProtocol , AjpAprProtocol, AjpNio2Protocol , Http11NioProtocol , Http11Nio2Protocol ,Http11AprProtocol 4)Adapter(适配器)由于协议不同,客户端发过来的请求信息也不尽相同,Tomcat定义了自己的 Request类来封装这些请求信息。ProtocolHandler接口负责解析请求并生成Tomcat Request类。但是这个Request对象不是标准的ServletRequest,不能用Tomcat Request作为参数来调用容器。Tomcat设计者的解决方案是引入CoyoteAdapter,这是适配器模式的经典运用,连接器调用 CoyoteAdapter的Sevice方法,传入的是Tomcat Request对象, CoyoteAdapter负责将Tomcat Request转成ServletRequest,再调用容器
四、Tomcat Servlet 容器 Catalina
1.Tomcat 模块分层结构图及Catalina位置
Tomcat是一个有一系列可配置的组件构成的Web容器(在conf/server.xml中配置),而Catalina是Tomcat的Servlet容器组件 我们先看一下Tomcat的模块封层结构图 从分层结构上很明显能看见: Tomcat 本质上就是一款 Servlet 容器, 因为 Catalina 才是 Tomcat 的核心 , 其他模块都是为Catalina 提供支撑的。 比如 : 通过 Coyote 模块提供链接通信,Jasper 模块提供 JSP 引 擎,Naming 提供JNDI 服务,Juli 提供日志服务
2.Servlet容器Catalina的结构
由于Catalina在Tomcat中的核心地位,一般可以直接认为Tomcat就是一个Catalina容器的实例 我们来看下它的结构图: Tomcat在启动的时候会初始化Catalina实例,Catalina实例通过加载server.xml完成其他实例的创建,从而创建并管理一个Server实例,Server实例创建并管理多个服务,每个服务又可以有多个Connector和一个Container 即: 一个Catalina实例(容器) 一个 Server实例(容器) 多个Service实例(容器) 每一个Service实例下可以有多个Connector实例和一个Container实例 Catalina:负责解析Tomcat的配置文件(server.xml) , 以此来创建服务器Server组件并进行管理 Server:服务器表示整个Catalina Servlet容器以及其它组件,负责组装并启动Servlaet引擎,Tomcat连接器。Server通过实现Lifecycle接口,提供了一种优雅的启动和关闭整个系统的方式 Service:服务是Server内部的组件,一个Server包含多个Service。它将若干个Connector组件绑定到一个 Container Container容器:负责处理用户的servlet请求,并返回对象给web用户的模块
3.Container 组件的具体结构
上面的Catalina结构图中看到Container组件容器中还有很多层,我们来一一分析下 Container组件下有几种具体的组件,分别是Engine、Host、Context和Wrapper。这4种组件(或者说容器)是父子关系。Tomcat通过一种分层的架构,使得Servlet容器具有很好的灵活性。 Engine(引擎):表示整个Catalina的Servlet引擎,用来管理多个虚拟站点,一个Service最多只能有一个Engine, 但是一个引擎可包含多个Host Host:代表一个虚拟主机,或者说一个站点,可以给Tomcat配置多个虚拟主机地址,而一个虚拟主机下可包含多个Context Context:表示一个Web应用程序, 一个Web应用可包含多个Wrapper Wrapper:表示一个Servlet,Wrapper 作为容器中的最底层,不能包含子容器 上述组件的配置其实就体现在conf/server.xml中 后面我们再继续进行server.xml文件配置的学习
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/1454.html