• Tomcat8源码笔记(六)连接器Connector分析


    根据 Tomcat8源码笔记(五)组件Container分析 前文分析,StandardService的初始化重心由 StandardEngine转移到了Connector的初始化,本篇记录下Connector实例化到初始化的过程

     

    国际惯例这个词最近很常见,那国际惯例,我先放上Tomcat各个组件结构图:Connector地位,一个Service下可以有多个Connector,和Container愉快的生活在Service里;

    image

    先来看看server.xml中对于Connector元素的位置以及如何定义:

    一个server.xml中确实可以定义多个Connector,按照官方注释的意思,一个连接器Connector代表了一个接受请求返回响应的端点,请求类型可以是HTTP、AJP这种;

    image

     

    废话少说,先来看下Tomcat如何解析Connector元素,并且生成怎么样的结构

    如果仔细看了前面几篇博客,直接进入Catalina的createStartDigester方法,找到Connector即可:

    image

    如果你不太了解Rule规则如何解析的,Tomcat8源码笔记(三)Catalina加载过程 也许可以帮你了解这是一个怎么样的流程;  从上面定义的规则,可以得到几点:

    1.ConnectorCreateRule这肯定是个动态的创建Connector的规则,与以往定义好了对象类型不一样.

    2.Connector实例化后会被Service调用addConnector,关联起来;或许还会有双向关联藏在哪里悄悄实现了.

    3.Connector也允许添加Listener子元素,监听器实现特殊的需求;

     

    Connector实例化

    按照经验,每个Connector实例化都会是这个逻辑:顺序调用rules的Rule对象的begin方法,然后顺序调用rules的Rule对象的body方法,最后逆序调用rules的Rule对象的end方法;

    image

     

    Step1.先从第一个规则ConnectorCreateRule的begin方法入手

    image

     

      Connector很多逻辑都在构造器中调用了,所以这里不得不先详细介绍下Connector构造器的方法:这里就以最常见的HTTP/1.1这种连接器来记录

    image

     

    首先是setProtocol方法:

    根据不同协议,初始化连接器的不同protocolClassName,HTTP/1.1在Tomcat8.0中使用的是Http11NioProtocol

    image

     

    其次是通过反射调用Http11NioProtocol的空参构造器实例化一个ProtocolHandler,最终目的是作为Connector的protocolHandler;果不其然,逻辑又在Http11NioProtocol的空参构造器中出现了!

    image

     

    Http11NioProtocol初始化

    endPoint初始化摸不清头脑

    image

     

    Http11ConnectionHandler初始化为了持有Http11NioProtocol,用来专门做一些处理; 还让endPoint持有了Http11ConnectionHandler,Http11NioProtocol初始化最后给endPoint设置了一堆属性,其实就是给endPoint的socketProperties属性设置。

    image

    最终,Http11NioProtocol初始化就完成了这样的结构:三者相互存在引用关系

    image_thumb8[1]

     

    Step2.Connector实例化的第二个规则说起,setAllPropertiesRule

    setAllPropertiesRule用来完成给Connector的属性赋值工作,比如常见的下面配置,就需要给Connector设置四个属性:port端口,protocol协议,connectionTimeout,redirectPort;

    port直接是Connector的属性设置即可,protocol之前也见过setProtocol方法,就是设置了protocolHandlerClassName属性,所以这一步重复了但是一定会执行做;redirectPort也是Connector属性,直接反射赋值;  connectionTimeout不是Connector属性,但是最终也有用啊,最后给了endPoint的socketProperties的 soTimeout属性!

    image

    Step3. 由于SetNextRule方法begin为空,所以直接Connector最基本的初始化差不多完成了!  而Rule规则,解析完成server.xml的一个元素就会按照end方法来逆序调用,所以这里起作用的是SetNextRule的end方法,而Tomcat8源码笔记(三)Catalina加载过程 这里记录过 SetNextRule的规则,在这里,就是给StandardService 调用addConnector添加连接器,所以StandardService的Connector默认情况就是两个了,HTTP/1.1和AJP/1.3这两种。

     

     

    Connector初始化

       终于进入到了Connector初始化,初始化了决定了Tomcat有资格接受HTTP等请求,Connector默认是没有监听器,所以初始化initInternal调用之前的触发监听统统忽略,直接进入正题 initInternal方法。

     

    image

    首先实例化了一个CoyoteAdapter,持有Connector实例;又让Http11NioProtocol持有CoyoteAdapter实例,Connector、CoyoteAdapter、Http11NioProtocol三者相互关联起来。设置

    Connector的parseBodyMethods为“POST”,parseBodyMethodsSet为{“POST”}.

     

    核心的就是Http11NioProtocol的初始化

      初始化了sslImplementation为了后续操作,调用父类的init方法.

    image

     

    Http11NioProtocol调用的父类初始化方法

    给NioEndPoint设置名称,http-nio-8080,这在日志信息中经常出现;最后就是调用NioEndPoint的初始化方法

    image

     

    Connector的初始化由Http11NioProtocol初始化,交给了NioEndPoint初始化

        NioEndPoint方法初始化没有交给别的组件来完成了! 自己调用自己的bind方法

    image

     

    bind方法

    典型的NIO编程,如果不熟悉的记得多看看NIO视频充下电,我也要抽空充下电。因为NioEndPoint端口设置过了8080,(这里留个悬念,我们只设置了Connector的8080端口,没设置NioEndPoint啊),另外给SocketChannel的socket都设置超时为 server.xml中配置的20000毫秒, 这是NIO编程部分得出的结论。  另外 acceptorThreadCount 是Acceptor线程的个数,pollerThreadCount是Poller线程的个数,poller线程个数取决于 Math.min(2,Runtime.getRuntime().availableProcessors()) ,这两个参数比较重要,后面会有Accpetor线程以及Poller线程具体分析。 最后调用NioSelectorPool的open方法.

    image

     

    NioSelectorPool的Open方法:

    image

     

    NioBlockingSelector的open方法:

    实例化BlockPoller对象,肯定是Thread的子类,作为守护线程运行,线程名称为:NioBlockingSelector.BlockPoller-1 , 啥时候用到我们再分析。

    image

     

     

    至此,Connector连接器我们就介绍了,总结下Connector初始化调用protocolHandler#init方法,protocol#init方法调用endPoint#init初始化,而endPoint初始化调用bind方法,采用NIO编程,由此可见Tomcat  HTTP1.1在Tomcat8中使用NIO编程来接受请求。  到这里Tomcat初始化工作都完成了,后面就是Tomcat启动并且接受请求的过程了,可见Tomcat部署项目、接受请求等等一系列都是启动中完成的,初始化只是准备工作。

     

  • 相关阅读:
    一日一技:微信开发-自定义菜单
    Redis五种数据结构
    .NET 5 部署在docker上运行
    一日一技:微信开发-发送模板消息
    Redis快速入门及应用
    面试官扎心一问:防止重复请求提交,有什么方案?
    在Windows上安装Docker
    上班摸鱼神器—VSCode 里也可以看股票 & 基金实时数据
    C# Nuget程序集StackExchange.Redis操作Redis 及 Redis 视频资源 及 相关入门指令 牛逼不,全都有
    Mongodb 更新某一条记录 C#
  • 原文地址:https://www.cnblogs.com/lvbinbin2yujie/p/10680496.html
Copyright © 2020-2023  润新知