上一篇主要是从各个容器的生命周期的角度讲了一下整个tomcat的运行流程,说明了各个容器之间的调用关系。但并没有太过详细的说明每一个组件并区分他们。

下面从功能的角度上详细的分析一下connector连接器。(下面的介绍会弱化一些调用关系,如果想知道各个组件之间的具体调用关系以及生命周期,可以查看上一篇文章。)

注:本篇是以tomcat8为例,不同版本的tomcat结构都有所不同。

首先,tomcat中一个Connector对应了一个请求,所以service容器中可以同时有多个connector对象。

Connector是使用protocolHandler来处理具体的请求(不同的protocolHandler代表不同的连接类型)。

而每种protocolHandler都使用了各自的3个重要组件来具体处理请求:

Endpoint:用于处理底层Socket连接(nio和nio2实现的是TCP/IP协议,Apr实现的是SSL/TLS协议)

Processer:用于将Endpoint接收到的Socket封装成Request(实现HTTP协议或websocket协议或AJP协议)

Adapter:用于将封装好的Request交给Container(将请求适配到servlet容器)

protocolHandler

每一个connector中实际上是使用protocolHandler来处理请求,protocolHandler接口是所有protocol类的顶层接口。

ProtocolHandler结构如下图:

首先,每个protocol的生命周期操作(start和init)是定义在它们的公共顶层抽象类AbstractProtocol中,所以每一个protocol的生命周期运行方式是一样的。

之后可以看出Protocol实际上分为了两种,即根据请求协议的不同:HTTP1.1和AJP1.3,有两种对应的ProtocolHandler。

这里说一下AJP协议:

AJP主要用于Tomcat的负载均衡,如nginx可以通过AJP协议向tomcat发送请求。

他存在以下优点:

1、发送的内容都是高度压缩的,所以流量消耗很少。

2、WEB服务器和SERVLET容器建立的是持久性tcp连接

3、性能比http更好(cpu使用率更低,时间略微更快)

缺点:

1、由于是持久连接,可能会导致连接数过多。

由图中可以看到,protocol有六个具体实现类,根据协议不同,各有两个。

每个子类之间的差距主要就是调用的endpoint不同。

每种协议的protocol都能选择三种endpoint(可以根据他们的名字来判断,如AjpAprProtocol和Http11AprProtocol调用的都是AprEndpoint)

下面主要讲一下Endpoint组件

Endpoint

endpoint组件结构如图所示,其中具体是执行方法startInternal()由三个子类自己进行覆写。

可以看出endpoint一共有三种,nio、nio2、apr。这三种其实都是不同的io方式,区别如下:

nio:

传统的java.io.*包是阻塞式的,即每一个请求都要占用一个线程,当并发数高时很占用资源。

而nio是非阻塞io,可以用少量的线程来处理大量的请求。

nio与传统io主要是在概念上不同,nio有三个新概念:Buffers/Channels/Selectors,

Channels是输入与读取的管道,其读写粒度为Block(Block的抽象就是Buffer,Buffer可以看成是一个缓冲区),所以用户从Channels管道中读到的数据实际上是Buffer,如果想往管道里添加数据,也得先将数据装到Buffer中。

Selector(选择器,多路复用器):轮询所有的注册通道,根据通道状态执行相关操作。状态包括:Connect,Accept,Read,Write。

在server端会创建一个Selector多路复用器,所有的客户端想和服务器建立连接都要创建一个SocketChannel注册到Selector上,然后Selector使用一个线程轮询着检测所有的注册的SocketChannel的状态,根据每个不同的通道的状态执行相关的代码。NIO的本质就是避免原始的TCP建立连接使用三次握手的操作,减少连接的开销。

nio2:

nio与nio2相比,nio被称为同步非阻塞,而nio2被称为异步非阻塞。可以看出nio2的关注点在异步上。

这种模式下用户只需要发起一个io然后返回,等IO操作真正的完成以后,应用程序会得到IO操作完成的通知,此时用户进程只需要对数据进行处理就好了,不需要进行实际的IO读写操作,因为真正的IO读取或者写入操作已经由内核完成了。

一个IO操作其实分成了两个步骤:发起IO请求和实际的IO操作。

同步IO和异步IO的区别就在于第二个步骤是否阻塞,如果实际的IO读写阻塞请求进程,那么就是同步IO。

阻塞IO和非阻塞IO的区别在于第一步,发起IO请求是否会被阻塞,如果阻塞直到完成那么就是传统的阻塞IO,如果不阻塞,那么就是非阻塞IO。

apr:

apr简单理解,就是从操作系统级别解决异步IO问题,大幅度的提高服务器的处理和响应性能, 也是Tomcat运行高并发应用的首选模式。

需要额外安装apr和native。使用了tomcat native技术之后,tomcat在跟操作系统级别的交互方面可以做得更好。

apr中socket的接收实际上是调用的native。

Tomcat-native是tomcat的一个子项目,一部分是用java写的,一部分是c写的。

Tomcat-native可以看做是一个集成包,里面集成了两个东西:openssl,这个是ssl信道的实现,另外一个是高性能的apr网络库(都是c写的)。

以后有机会再深入了解这一块。

Processer

endpoint建立好socket连接后,会将请求继续发送给Processer进行封装成request和response,processer结构图如下:

首先可以看出Processor在抽象类上分为了两类,先说第一种UpgradeProcessorBase。

之前也说过Processor是用来根据应用层协议将socket中的内容封装进request和response中的。

而在protocol组件结构中可以看出,tomcat支持两种应用层协议:AJP1.3和HTTP1.1。

此处的UpgradeProcessorBase是用来处理HTTP的升级协议WebSocket的。

说明一下WebSocket协议:

websocket协议是html5提出的一个规范。

websocket协议最突出的一点是:服务器和客户端可以在规定的时间范围内相互推送消息(而传统的Http协议服务端只能等客户端发送请求后再返回消息)。

websocket协议先通过http发送一条特殊的http请求进行握手后创建一共用于交换数据的TCP连接,之后服务端与客户端的相互推送都是通过此tcp连接进行。

所以第一次的特殊http请求用的还是Http11Processor组件,然后Http11Processor处理之后,如果Socket状态为UPGRADING,那么接下来Endpoint会创建并调用UpgradeProcessorBase来处理。

同理,Http11Processor是用来处理http1.1协议。AjpProcessor是用来处理AJP协议。

接下来比较重要的问题是:processor在什么时候,如何封装的request和response?

创建request和response对象的相关代码如下:

public AbstractProcessor(AbstractEndpoint<?> endpoint) {
this(endpoint, new Request(), new Response());
}

这是AbstractProcessor的构造函数,也就是说,当子类processor被创建时,就会新建request和response对象。

先说org.apache.coyote.Request

这个Request和我们在servlet中使用的HttpServletRequest不同,这个Request是用来在tomcat内部使用的,里面的很多方法都不希望暴露给开发人员。

所以此处使用了适配器模式,用户实际上操作的是org.apache.catalina.connector.Request

之后调用adapter的service(this.request, this.response),将request和response传给adapter

adapter

adapter接口只有一个实现类,该实现类不在org.apache.coyote包中(之前的组件都在该包中),而是org.apache.catalina.connector包中的coyoteAdapter类。

至此,Adapter的service方法获取到request和response后调用Container管道中的invoke方法继续处理请求。

传输的代码是:

connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);

即:先从Connector中获取service,然后从service中获取Container。接着再获取管道,再获取管道的第一个值Value,最后调用invoke()方法执行请求。

深入理解Connector的更多相关文章

  1. Chapter 4: Tomcat Default Connector

    一.概述 第三章介绍的connector是一个很好的学习工具,但是我们还可以做的更多.这一章介绍的是Tomcat4默认的connector. 一个Tomcat的connector是一个独立的模块,能够 ...

  2. TCP Socket Http关系

    理解Tomcat内部处理网络数据的机制同时需要了解相关的一些术语,这样我们在阅读源码的时候能更加清楚的理解Connector下使用到的Socket通信原理. TCP/IP: 数据在网络传输是基于TCP ...

  3. Tomcat源码分析 (八)----- HTTP请求处理过程(一)

    终于进行到Connector的分析阶段了,这也是Tomcat里面最复杂的一块功能了.Connector中文名为连接器,既然是连接器,它肯定会连接某些东西,连接些什么呢? Connector用于接受请求 ...

  4. Netron开发快速上手(一):GraphControl,Shape,Connector和Connection

    版权所有,引用请注明出处:<<http://www.cnblogs.com/dragon/p/5203663.html >> 本文所用示例下载FlowChart.zip 一个用 ...

  5. 理解 OpenStack + Ceph (5):OpenStack 与 Ceph 之间的集成 [OpenStack Integration with Ceph]

    理解 OpenStack + Ceph 系列文章: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 (5)Ceph 与 OpenS ...

  6. 转!!深入理解 Session 与 Cookie

    摘要 Session 与 Cookie 不管是对 Java Web 的初学者还是熟练使用者来说都是一个令人头疼的问题.在初入职场时恐怕很多程序员在面试的时候都被问到过这个问题.其实这个问题回答起来既简 ...

  7. Chapter 3: Connector(连接器)

    一.概述 Tomcat或者称之为Catalina(开发名称),可以简化为两个主要的模块,如下图: 多个Connector关联一个Container.之所以需要多个Connector,是为了处理多种协议 ...

  8. 1、Web容器的理解&Tomcat的安装与配置

    Web容器的理解 <Java Web开发实战经典——基础篇>一书中对Web容器这一概念阐述得很好,借用其观点对Web容器加以理解: 想要运行一个Java Web的程序,则必须有相应的Web ...

  9. tomcat Connector 连接器

    连接器的核心功能,本文去除非核心功能,留下整个程序的框架,便于理解. 1.接受连接请求 2.创建request,和response. 3.调用容器对应的Invoke方法, 首先看类的依赖结构. 1.C ...

随机推荐

  1. 荧光原位杂交技术 RNA-FiSH (fluorescence in situ hybridization)

    通俗理解:带有荧光标记的DNA探针可以用于检测活体内特定基因的表达情况,活体成像. 荧光原位杂交方法是一种物理图谱绘制方法,使用荧光素标记探针,以检测探针和分裂中期的染色体或分裂间期的染色质的杂交.荧 ...

  2. 非常棒的——python Deep learning 学习笔记

    https://www.cnblogs.com/zhhfan/p/9985991.html

  3. 基于bootstrap模态框的日期选择器

    近来由于工作需求,以bootstrap模态框+DIV+CSS+JS做了一个适用于移动端的日期选择器,能够满足多样的需求,目前处于第一个版本,后续可能会继续更新.废话不多说,直接进入制作过程. 首先,需 ...

  4. LeetCode--026--删除排序数组中的重复项

    问题描述: 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成 ...

  5. Linux命令详解-file

    file命令用来识别文件类型,也可用来辨别一些文件的编码格式.它是通过查看文件的头部信息来获取文件类型,而不是像Windows通过扩展名来确定文件类型的. 1.命令格式: file [ -bchikL ...

  6. 2017-2018 ACM-ICPC Latin American Regional Programming Contest D.Daunting device

    题意:一个数组n个操作每次先查询p颜色的数量然后求出区间,区间染色成x,然后求最大染色数 题解:odt裸题,多维护一个color个数数组就好了 //#pragma comment(linker, &q ...

  7. bzoj3676: [Apio2014]回文串 pam

    题意:字符串s.我们定义s的一个子串t的"出 现值"为t在s中的出现次数乘以t的长度.请你求出s的所有回文子串中的最 大出现值. 题解:pam板子题 //cnt数组表示该节点代表的 ...

  8. html和jsp的区别及优缺点

    ♥ HTML(Hypertext Markup Language)文本标记语言,它是静态页面,和JavaScript一样解释性语言,为什么说是解释性语言呢?因为,只要你有一个浏览器那么它就可以正常显示 ...

  9. vue项目 sockjs-node一直报错问题

    vue3下 vue.config.js中 devServer: { host: '0.0.0.0', port: 8080, proxy: { '/': { target: 'http://127.0 ...

  10. 安卓——AlertDialog多样按钮

    在xml 设计页面添加标签 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmln ...