Tomcat8源码笔记(六)连接器Connector分析
根据 Tomcat8源码笔记(五)组件Container分析 前文分析,StandardService的初始化重心由 StandardEngine转移到了Connector的初始化,本篇记录下Connector实例化到初始化的过程
国际惯例这个词最近很常见,那国际惯例,我先放上Tomcat各个组件结构图:Connector地位,一个Service下可以有多个Connector,和Container愉快的生活在Service里;
先来看看server.xml中对于Connector元素的位置以及如何定义:
一个server.xml中确实可以定义多个Connector,按照官方注释的意思,一个连接器Connector代表了一个接受请求返回响应的端点,请求类型可以是HTTP、AJP这种;
废话少说,先来看下Tomcat如何解析Connector元素,并且生成怎么样的结构
如果仔细看了前面几篇博客,直接进入Catalina的createStartDigester方法,找到Connector即可:
如果你不太了解Rule规则如何解析的,Tomcat8源码笔记(三)Catalina加载过程 也许可以帮你了解这是一个怎么样的流程; 从上面定义的规则,可以得到几点:
1.ConnectorCreateRule这肯定是个动态的创建Connector的规则,与以往定义好了对象类型不一样.
2.Connector实例化后会被Service调用addConnector,关联起来;或许还会有双向关联藏在哪里悄悄实现了.
3.Connector也允许添加Listener子元素,监听器实现特殊的需求;
Connector实例化
按照经验,每个Connector实例化都会是这个逻辑:顺序调用rules的Rule对象的begin方法,然后顺序调用rules的Rule对象的body方法,最后逆序调用rules的Rule对象的end方法;
Step1.先从第一个规则ConnectorCreateRule的begin方法入手
Connector很多逻辑都在构造器中调用了,所以这里不得不先详细介绍下Connector构造器的方法:这里就以最常见的HTTP/1.1这种连接器来记录
首先是setProtocol方法:
根据不同协议,初始化连接器的不同protocolClassName,HTTP/1.1在Tomcat8.0中使用的是Http11NioProtocol
其次是通过反射调用Http11NioProtocol的空参构造器实例化一个ProtocolHandler,最终目的是作为Connector的protocolHandler;果不其然,逻辑又在Http11NioProtocol的空参构造器中出现了!
Http11NioProtocol初始化
endPoint初始化摸不清头脑
Http11ConnectionHandler初始化为了持有Http11NioProtocol,用来专门做一些处理; 还让endPoint持有了Http11ConnectionHandler,Http11NioProtocol初始化最后给endPoint设置了一堆属性,其实就是给endPoint的socketProperties属性设置。
最终,Http11NioProtocol初始化就完成了这样的结构:三者相互存在引用关系
Step2.Connector实例化的第二个规则说起,setAllPropertiesRule
setAllPropertiesRule用来完成给Connector的属性赋值工作,比如常见的下面配置,就需要给Connector设置四个属性:port端口,protocol协议,connectionTimeout,redirectPort;
port直接是Connector的属性设置即可,protocol之前也见过setProtocol方法,就是设置了protocolHandlerClassName属性,所以这一步重复了但是一定会执行做;redirectPort也是Connector属性,直接反射赋值; connectionTimeout不是Connector属性,但是最终也有用啊,最后给了endPoint的socketProperties的 soTimeout属性!
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方法。
Connector的parseBodyMethods为“POST”,parseBodyMethodsSet为{“POST”}.
核心的就是Http11NioProtocol的初始化
初始化了sslImplementation为了后续操作,调用父类的init方法.
Http11NioProtocol调用的父类初始化方法
给NioEndPoint设置名称,http-nio-8080,这在日志信息中经常出现;最后就是调用NioEndPoint的初始化方法
Connector的初始化由Http11NioProtocol初始化,交给了NioEndPoint初始化
NioEndPoint方法初始化没有交给别的组件来完成了! 自己调用自己的bind方法
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方法.
NioSelectorPool的Open方法:
NioBlockingSelector的open方法:
实例化BlockPoller对象,肯定是Thread的子类,作为守护线程运行,线程名称为:NioBlockingSelector.BlockPoller-1 , 啥时候用到我们再分析。
至此,Connector连接器我们就介绍了,总结下Connector初始化调用protocolHandler#init方法,protocol#init方法调用endPoint#init初始化,而endPoint初始化调用bind方法,采用NIO编程,由此可见Tomcat HTTP1.1在Tomcat8中使用NIO编程来接受请求。 到这里Tomcat初始化工作都完成了,后面就是Tomcat启动并且接受请求的过程了,可见Tomcat部署项目、接受请求等等一系列都是启动中完成的,初始化只是准备工作。
Tomcat8源码笔记(六)连接器Connector分析的更多相关文章
- Tomcat8源码笔记(五)组件Container分析
Tomcat8源码笔记(四)Server和Service初始化 介绍过Tomcat中Service的初始化 最先初始化就是Container,而Container初始化过程是咋样的? 说到Contai ...
- Tomcat8源码笔记(七)组件启动Server Service Engine Host启动
一.Tomcat启动的入口 Tomcat初始化简单流程前面博客介绍了一遍,组件除了StandardHost都有博客,欢迎大家指文中错误.Tomcat启动类是Bootstrap,而启动容器启动入口位于 ...
- Tomcat8源码笔记(三)Catalina加载过程
之前介绍过 Catalina加载过程是Bootstrap的load调用的 Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...
- Tomcat8源码笔记(四)Server和Service初始化
上一章 简单说明下Tomcat各个组件: Server:服务器,Tomcat服务器,一个Tomcat只有一个Server组件; Service:业务层,是Server下最大的子容器,一个Server可 ...
- Tomcat8源码笔记(八)明白Tomcat怎么部署webapps下项目
以前没想过这么个问题:Tomcat怎么处理webapps下项目,并且我访问浏览器ip: port/项目名/请求路径,以SSM为例,Tomcat怎么就能将请求找到项目呢,项目还是个文件夹类型的? Tom ...
- Tomcat8源码笔记(一)Lifecycle接口
第一次阅读Tomcat8源码,就以Lifecycle作为笔记阅读的开篇吧,一千个读者就有一千个哈姆雷特,每个人都Tomcat的理解都不同,如果不记录一次Tomcat源码可能忘了就忘了. 断断DEBUG ...
- Tomcat8源码笔记(二)Bootstrap启动
TOMCAT源码调试入口是Bootstrap类的main方法,我的启动参数VM: -Dcatalina.home=E:/Tomcat_Source_Code/apache-tomcat-8.0.53- ...
- Tomcat8源码笔记(九)组件StandardContext启动流程--未完待续
StandardContext代表的是webapps下项目,一个项目就是一个StandardContext,作为Tomcat组件的一部分,就会实现Lifecycle接口,被Tomcat管理着生命周期, ...
- 厉害!这份阿里面试官 甩出的Spring源码笔记,GitHub上已经爆火
前言 时至今日,Spring 在 Java 生态系统与就业市场上,面试出镜率之高,投产规模之广,无出其右.随着技术的发展,Spring 从往日的 IoC 框架,已发展成 Cloud Native 基础 ...
随机推荐
- HTTP协议 与 TCP协议 的区别
TCP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据. TCP/IP和HTTP协议的关系,从本质上来说,二者没有可比性,我们在传输数据时,可以只使用(传输 ...
- git的基本使用和问题
1,填写信息git config --global user.name "用户名"git config --global user.email "邮箱" 2,创 ...
- Django积木块五——分页
分页 django本身带有分页功能,为什么要用他呢?因为它的代码更为简洁,并且在做筛选的时候会把url中的所有参数都组装起来,并且加上分页.也就是做筛选中的结果也可以用这个分页. pip instal ...
- java(一) 基础部分
1.11.简单讲一下java的跨平台原理 Java通过不同的系统.不同版本.不同位数的java虚拟机(jvm),来屏蔽不同的系统指令集差异而对外体统统一的接口(java API),对于我们普通的jav ...
- 解压->静态库.a文件
1. cd /Volumes/HHD/PQS/apple/Public 2. file com_PQS.a com_PQS.a: Mach-O universal binary with 5 arch ...
- vue.js 2.0(2)
1.双向绑定v-model要写在输入框里 2.点击改变颜色:当index和isActive统一时,才会调用class html: function: css: 3.在同一 ...
- 7 week work
Dom和Bom的起源.方法.内容.应用. Dom:起源:首先听到Virtual DOM这个概念应该来自于React,并且在不了解时觉得这个概念是一个逼格特别高的词.其实任何技术的诞生都是有相应的历史的 ...
- Charles 学习笔记
之前接触过抓包工具Fiddler,一直在Windows下使用,感觉还是挺好用的.今天接触了Charles才有了了解,首先Charles设计的比较美丽,而且页面布局也是简单易学的,但这两款抓包工具本质的 ...
- 微信内转发APP及h5类域名怎么做到防封防拦截,微信域名防红技术原理
我们常常遇到自己正规的网站链接,无端被微信拦截,大家都为这问题苦恼不已.但凡想使用微信来推广产品或者从事活动营销的用户,就一定会遇到域名被微信拦截甚至封停的情况.域名没被封过,那你的营销人生肯定是不完 ...
- [转]Linux操作系统tcpdump抓包分析详解
PS:tcpdump是一个用于截取网络分组,并输出分组内容的工具,简单说就是数据包抓包工具.tcpdump凭借强大的功能和灵活的截取策略,使其成为Linux系统下用于网络分析和问题排查的首选工具. t ...