首页 > 其他分享 >【Tomcat】【五】Connector 分析

【Tomcat】【五】Connector 分析

时间:2023-03-20 23:46:38浏览次数:42  
标签:分析 调用 HTTP Tomcat 处理 Connector ProtocolHandler 方法

1  前言

  Connector用于接收请求并将请求封装成 Request 和 Response 来具体处理,最底层是使用Socket 来进行连接的,Request 和 Response 是按照HTTP 协议来封装的,所以 Connector 同时实现了TCP/IP协议和HTTP 协议,Request和 Response 封装完之后交给 Container 进行处理Container 就是 Servlet 的容器,Container处理完之后返回给 Connector,最后 Connector 使用Socket将处理结果返回给客户端,这样整个请求就处理完了。

2  Connector的结构

  Connector中具体是用 ProtocolHandler 来处理请求的,不同的 ProtocolHandler 代表不同的连接类型,比如,Httpl1Protocol使用的是普通 Socket 来连接的,Http11NioProtocol使用的是NioSocket 来连接的。

  ProtocolHandler 里面有3个非常重要的组件:Endpoint、Processor和Adapter。Endpoint用于处理底层Socket的网络连接,Processor 用于将Endpoint 接收到的Socket封装成Request,Adapter用于将封装好的 Request交给 Container 进行具体处理。也就是说Endpoint用来实现TCP/IP协议,Processor 用来实现HTTP 协议,Adapter 将请求适配到 Servlet 容器进行具体处理。

  Endpoint 的抽象实现AbstractEndpoint 里面定义的Acceptor 和AsyncTimeout 两个内部类和一个Handler 接口。Acceptor 用于监听请求,AsyncTimeout 用于检查异步 request 的超时Handler 用于处理接收到的 Socket,在内部调用了 Processor 进行处理。

  

3  Connector自身类

  Connector类本身的作用主要是在其创建时创建 ProtocolHandler,然后在生命周期的相关方法中调用了 ProtocolHandler 的相关生命周期方法。Connector 的使用方法是通过 Connector标签配置在 conf/server.xml文件中,所以 Connector 是在 Catalina 的 load 方法中根据 conf/server.xml配置文件创建Server 对象时创建的。Connector 的生命周期方法是在 Service 中调用的。

3.1  Connector的创建

  Connector 的创建过程主要是初始化 ProtocolHandler。serverxml配置文件中Connector标签的 protocol属性会设置到Connector构造函数的参数中,它用于指定 ProtocolHandler的类型,Connector的构造函数代码如下:

  

  这里首先根据传人的 protocol参数调用 setProtocol方法设置了 protocolHandlerClassName 属性,接着用 protocolHandlerClassName 所代表的类创建了 ProtocolHandler 并赋值给了 protocol-Handler 属性。

  设置protocolHandlerClassName 属性的 setProtocol方法代码如下:

  

   

  Apr是Apache Portable Runtime 的缩写,是Apache提供的一个运行时环境,如果要使用Apr需要先安装,安装后Tomcat 可以自已检测出来。如果安装了Apr,setProtocol方法会根据配 置的HTTP/1.1属性对应地将 protocolHandlerClassName 设 置为 orgapache.coyote.htpl1.Httpl1AprProtocol,如果没有安装 Apr,会根据配置的HTTP/1.1属性将 protocolHandler-ClassName 设 置为 orgapache.coyote.httpl1.Htpl1NioProtocol,然后就会根 据 protocol-HandlerClassName来创建 ProtocolHandler。

3.2  Connector生命周期处理方法

  Connector的生命周期处理方法中主要调用了 ProtocolHandler 的相应生命周期方法,代码如下:

  

   

  在initInternal方法中首先新建了一个Adapter 并设置到 ProtocolHandler 中,然后对ProtocolHandler 进行初始化;在 startIntermal方法中首先判断设置的端口是否小于0,如果小于0就抛出异常,否则就调用 ProtocolHandler 的 start 方法来启动;在 stopnternal方法中先设置了生命周期状态,然后调用了 ProtocolHandler 的 stop 方法;在 destroyInternal方法中除了调用 ProtocolHandler 的 destroy 方法,还会将当前的 Connector 从 Service 中删除并调用父类的destroyInternal方法。

4  ProtocolHandler

  Tomcat 中ProtocolHandler 的继承结构如图7-7所。ProtocolHandler有一个抽象实现类AbstractProtocolAbstractProtocol下面分了三种类型:Ajp、HTTP和Spdy。Ajp是ApacheJServ Protocol的缩写,Apache的定向包协议,主要用于与前端服务器(如Apache)进行通信,它是长连接,不需要每次通信都重新建立连接,这样就节省了开销;HTTP协议前面已经介绍过了,就不重复介绍了;Spdy 协议是 Google开发的协议,作用类似HTTP,比HTTP 效率高,不过这只是Google 制定的企业级协议,使用并不广泛,而且在HTTP/2 协议中已经包含了 Spdy 所提供的优势,所以Spdy 协议平常很少使用,不过 Tomcat 提供了支持。

  这里的 ProtocolHandler 以默认配置中的 orgapache.coyote.http11.Httpl1NioProtocol 为例来分析,它使用HTTP11协议,TCP 层使用NioSocket 来传输数据。Http11NioProtocol的构造函数中创建了 NioEndpoint类型的Endpoint,并新建了Http11-ConnectionHandler类型的Handler 然后设置到了 Endpoint中,代码如下:

  四个生命周期方法是在父类AbstractProtocol 中实现的,其中主要调用了 Endpoint 的生命周期方法。

5  处理TCP/IP协议的Endpoint

  Endpoint用于处理具体连接和传输数据,NioEndpoint继承自orgapache.tomcat.utilnetAbstractEndpoint,在NioEndpoint 中新增了 Poller和 SocketProcessor 内部类,NioEndpoint中处理请求的具体流程如图7-8 所示。

  

   NioEndpoint的init和start 方法在父类AbstractEndpoin 中,代码如下:

  

  这两个方法主要调用bind和startInternal方法,它们是模板方法,在NioEndpoint中实现,bind方法代码如下:

  

   

  这里的 bind方法中首先初始化了 ServerSocketChannel,然后检查了代表Acceptor 和Poller初始化的线程数量的 acceptorThreadCount 属性和 pollerThreadCount 属性,它们至少为1,Acceptor 用于接收请求,接收到请求后交给 Poller 处理,它们都是启动线程来处理的。另外还处理了初始化SSL等内容。

  NioEndpoint的startInternal方法代码如下:

  

   这里首先初始化了一些属性,然后启动了 Poller 和Acceptor 来处理请求,初始化的属性中的 processorCache属性是 SynchronizedStack<SocketProcessor>类型,SocketProcessor 并不是前面介绍的 Processor,而是 NioEndpoint 的一个内部类,Poller 接收到请求后就会交给它处理,SocketProcessor 又会将请求传递到 Handler。启动 Acceptor 的 startAcceptorThreads 方法在AbstractEndpoint中,代码如下:

  

   这里的getAcceptorThreadCount方法就是获取的init方法中处理过的acceptorThreadCount属性,获取到后就会启动相应数量的 Acceptor 线程来接收请求。

6  处理HTTP协议的Processor

  Processor 用于处理应用层协议(如HTTP),它的继承结构如图所示。

  

  Processor有两个AbstractProtocol抽象继承类,图7-9中上面的AbstractProtocol是在orgapache.coyote.httpll.upgrade 包中,下面的AbstractProtocol在 orgapache.coyote 包中。正常处理协议使用的是下面的AbstractProtocol及其实现类,上面的AbstractProtocol是 Servlet3.1之后才新增的,用于处理HTTP的升级协议,当正常(下面)的 Processor 处理之后如果Socket 的状态是UPGRADING,那么Endpoint 中的Handler将会接着创建并调用orgapache.coyote.httpll.upgrade包中的 Processor 进行处理,这里的HTTP升级协议指的是WebSocket 协议。

  图中下方orgapache.coyote包中的Processor 和前面介绍过的ProtocolHandler一一对应,这里就不详细解释了,具体实现应用层协议处理请求的是 AbstractAipProcessor 和Abst-ractHttp11Processor 中的 process方法,这个方法中首先封装了Request和 Response,然后调用Adapter将请求传递到了Container 中,最后对处理的结果进行了处理,如有没有启动异步处理、处理过程中有没有抛出异常等。

7  适配器Adapter

  Adapter 只有一个实现类,那就是 org.apache.catalina.connector包下的 CoyoteAdapter类Processor在其 process 方法中会调用Adapter 的service方法来处理请求,Adapter 的 service方法主要是调用Container 管道中的invoke方法来处理请求,在处理之前对 Request和 Response做了处理,将原来创建的org.apache.coyote 包下的 Request 和 Response 封装成了org.apache.catalina.connector的 Request和 Response,并在处理完成后判断是否启动了 Comet(长连接推模式)和是否启动了异步请求,并作出相应处理。调用Container 管道的相应代码片段如下:

  

   这里首先从Connector 中获取到 Service(Connector在initInternal方法中创建Coyote-Adapter 的时候已经将自已设置到了 CoyoteAdapter 中),然后从 Service 中获取 Container,接着获取管道,再获取管道的第一个 Value,最后调用invoke 方法执行请求。Service 中保存的是最顶层的容器,当调用最顶层容器管道的 invoke 方法时,管道将逐层调用各层容器的管道中Value 的invoke方法,直到最后调用 Wrapper 的管道中的 BaseValue (StandardWrapperValve)来处理Filter和Servlet。

8  小结

  本文我们主要看了下 Connector的组成以及实现过程,有理解不对的地方欢迎指正哈。

标签:分析,调用,HTTP,Tomcat,处理,Connector,ProtocolHandler,方法
From: https://www.cnblogs.com/kukuxjx/p/17238382.html

相关文章

  • R语言中贝叶斯网络(BN)、动态贝叶斯网络、线性模型分析错颌畸形数据|附代码数据
    全文链接:http://tecdat.cn/?p=22956最近我们被客户要求撰写关于贝叶斯网络的研究报告,包括一些图形和统计输出。贝叶斯网络(BN)是一种基于有向无环图的概率模型,它描述了一组......
  • 【Tomcat】【三】Container 分析
    1 前言这节我们来看下Container哈,一样边看边记录一下,先通读一遍理解,理解完再记录加强一遍。2  ContainerBase的结构Container是Tomcat中容器的接口,通......
  • PYTHON银行机器学习:回归、随机森林、KNN近邻、决策树、高斯朴素贝叶斯、支持向量机SV
    全文下载链接:http://tecdat.cn/?p=26219最近我们被客户要求撰写关于银行机器学习的研究报告,包括一些图形和统计输出。该数据与银行机构的直接营销活动相关,营销活动基于电......
  • 因果推断dowhy之-探索酒店取消预订的原因分析
    0x01.DoWhy案例分析本案例依旧是基于微软官方开源的文档进行学习,有想更深入了解的请移步微软官网。背景:取消酒店预订可能有不同的原因。客户可能会要求一些无法提供的东西......
  • 数据分析
    浏览数据,查看列名读取文件(内涵类 型转换)numpyNp.local(路径,allow_pickle=True) pandas的pd.read_Excel(路径,*) *header=0列索引,index_col行索引,she......
  • 配置tomcat虚拟目录
    虚拟目录的作用:可以发布任意目录下的项目1、编辑tomcat目录下的conf目录下的server.xml,找到<Host>标签2、加入以下内容:<Contextpath="/webdemo" docBase="D:/myweb"......
  • hashmap,hashtabl,hashtree,linkedhashmap区别分析
    java为数据结构中的映射定义了一个接口java.util.Map;它有四个实现类,分别是HashMapHashtableLinkedHashMap和TreeMap.Map主要用于存储健值对,根据......
  • 计算机系统性能评价与性能分析
    参考:https://foxsen.github.io/archbase/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%B3%BB%E7%BB%9F%E6%80%A7%E8%83%BD%E8%AF%84%E4%BB%B7%E4%B8%8E%E6%80%A7%E8%83%BD%E5%88%86%E6%......
  • mysql索引、优化、sql性能分析
    为什么InnoDB存储引擎选择使用B+tree索引结构?相对于二叉树,层级更少,搜索效率高对于B-tree,无论是叶子节点还是非叶子节点,都会保存数据,这样导致一页中存储的键值减少,指针......
  • tomcat配置虚拟路径,供用户访问静态资源
    tomcat配置虚拟路径,供用户访问静态资源在实际开发中,后台需要提供给用户访问静态资源,而且该静态资源不是在tomcat中,即不是在web目录下,那么用户是不能访问的,这时,需要配置tomc......