探究tomcat7源码的connector
来源:互联网 发布:搞笑相机软件大全 编辑:程序博客网 时间:2024/05/21 18:50
了解tomcat的整体启动后,我们再来聊一聊tomcat的connector,也就是负责连接和协议处理的模块
1、下图笔者将主要类图提取出来,先看看Connector的UML类图
Connector:不用多说,就是连接器本身,包含两个组件Adapter和ProtocolHandler
Adapter:提供service方法,负责invoke Container中的具体业务代码,将ProtocolHandler的数据封装成javax.servlet.http.HttpServletRequest与javax.servlet.http.HttpServletReponse,将http请求数据转化为业务型数据,如构建sessionID、解析URL中的参数、MessageBytes解码等,tomcat给了默认实现CoyoteAdapter实现
ProtocolHandler:负责协议发连接的接口,并提供基础的解析,如http头部、内容长度、长连接维护等。抽象实现为AbstractProtocol,AbstractProtocol的具体实现有AjpAprProtocol、AjpNioProtocol、AjpProtocol、Http11NioProtocol、Http11Protocol、Http11AprProtocol(tomcat8以后可能会更多)等,各个实现类分别实现不同的应用层协议和传输层协议
AbstractEndpoint:负责底层的socket连接,如端口绑定与解绑、长连接管理、ssl连接、处理socket延迟、控制tcp连接数、管理执行器(Executor)等,具体实现类有AprEndpoint、JIoEndpoint、NioEndpoint等
Executor:负责监听端口数据,维护线程池,并将监听的socket放到数据放到线程池运行,ThreadPoolExecutor是其中一个具体实现类,也是tomcat7默认实现类
AbstractEndpoint.Acceptor:实现Runnable接口,单条线程等待socket的连接
AbstractEndpoint.Handler:协议状态管理,里面提供了socket状态枚举、回收等方法,主要用于维护socket的状态
AbstractConnectionHandler:继承的基础上新增了创建process、管理process的功能,并且能够根据不同的socket状态创建process
Process:具体的socket上层的协议处理任务,并且构造成org.apache.coyote.Request、org.apache.coyote.Response,管理Comet技术、Async技术、长连接管理(此处是协议上层的长连接,并不是socket层的长连接),具体实现类有AbstractAjpProcessor、AbstractHttp11Processor
AbstractInputBuffer:负责HTTP协议解析,如将解析请求头转化为MimeHeaders对象、将post数据封装成InputStream数据等,具体实现类有InternalAprInputBuffer、InternalInputBuffer、InternalNioInputBuffer等
2、把这些基本构件及其大概的功能搞清楚后,下面我们就来分析一次http请求过来了服务端都干了些什么
先提供一张笔者画的时序图
首先AbstractEndpoint在启动时会创建线程池监听客户端请求,一个线程对应一个Acceptor,通过强制子类实现getLocalPort、bind、startInternal、createAcceptor等方法实现具体的socket连接,每个Acceptor里面的run方法都会监听同一个serverSocket。AbstractEndpoint还会提供startAcceptorThreads方法启动所有线程
startAcceptorThreads方法如下图
如图可知,每个Acceptor都需要createAcceptor方法创建,我们再来看看createAcceptor方法
可知,这个方法需要具体的子类实现,我们看看其中一个子类JIoEndpoint的实现
我们再看看JIoEndpoint是如何实现这个Acceptor子类的
这里我们看到,Acceptor的实现里面会去监听serverSocket,也就是所有的Acceptor都会监听同一个serverSocket,这样就实现了并发请求。所以正常情况下,如果没有连接到来时线程会阻塞在这里。
下面我们继续看看如果有新的连接过来了会怎么样
我们看到运行了processSocket方法,我们再具体看看这个方法
上图可知,我们在代码的533行看到直接将socket扔到了Executor里去处理,而我们之前说过,tomcat7的默认实现是ThreadPoolExecutor处理,因此我们可以得出结论:维持tcp连接的线程与‘处理这个连接’的线程不是同一线程
接下来我们再看看这个‘处理这个连接’线程做了些什么,也就是SocketProcessor这个东西
我们看到,他会做一些socket的连接状态判断,如果不是关闭状态的,则会运行handler的process方法,我们继续寻找这个process的具体实现类的方法,前面,根据以上的UML类图可查询到,这个实现类在AbstractProtocol里面有抽象的实现AbstractConnectionHandler,主要用于协调socket处理与上层协议处理,我们看看他是如何协调的
我们看到这里是通过创建的processor来协调的,前面知道processor主要用于上层协议的处理,这里显然已经开始从socket层到应用层协议转化了,我们先看看这个processor是如何生成的。经过查找,我们知道这个对象的生成是通过抽象方法createProcessor获取的,也就是说需要AbstractConnectionHandler的子类去实现创建这个processor的方法,我们挑选其中一个子类AjpProtocol.AjpConnectionHandler去看看是如何实现的
创建的是一个AjpProcessor的实例,我们就再进这个AjpProcessor的process方法里面看看是如何解析这个协议的
我们看到了调用了adapter的service方法而在上面我们知道,Tomcat7默认的Adapter实现是CoyoteAdapter,所以我们只需要查看CoyoteAdapter的service方法即可
我们看到了,服务由这里调用了Container的方法,那就是tomcat的另一个模块了
3.关于AbstractInputBuffer
可能有细心的读者发现了,上图中的AbstractInputBuffer并未出现在请求的流程中,这是因为笔者举的例子是AJP协议,所以上面挑选的process协议处理类为AjpProtocol.AjpConnectionHandler,而在HTTP的协议里面可以看到AbstractInputBuffer参与解析
- 探究tomcat7源码的connector
- Tomcat7.0.42源码研读之网络连接器Connector(三)
- Tomcat7-Connector(连接器)学习
- Tomcat7源码的环境搭建
- 探究 ACE 的 Proactor_Test 示例中的 Acceptor 和 Connector 分别如何与 Proactor 关联。
- tomcat源码:Connector模块
- tomcat源码浅析--connector
- Jetty源码分析之NIO实现的Connector:SelectChannelConnector
- Set接口的iterator方法源码探究
- Spring的四种Advice源码探究
- ActivityGroup的用法以及源码探究
- SGISTL源码探究-迭代器的类型
- SGISTL源码探究-pair的实现
- 如何走进Tomcat源码的探究
- tomcat源码分析之connector
- Tomcat源码之Connector (1)
- Tomcat源码 Connector(2)
- Tomcat源码分析之Connector
- Java中的修饰符区别(public,private,protected,default, final)
- POJ 3695 Rectangles 笔记
- springmvc为请求处理器的目标参数赋值的过程
- 用线性表实现约瑟夫环(java版)
- DLX模板之精确覆盖和重复覆盖
- 探究tomcat7源码的connector
- POJ3621 Sightseeing Cows 最短路求最优比率生成环
- 按键精灵之复制文本到播放器中-yellowcong
- ios-UILabel的自动换行
- ios UIWebView捏合放大缩小的实现
- 午后心情
- VSCode C++编译调试 Mac
- 归并排序
- Qt学习:QLineEdit的程序示例