Tomcat连接器Connector源码解读(一)架构概览,tomcat面试题2024

从实现类来看,Tomcat的连接器主要支持两种协议:HTTP/1.1协议和AJP协议,实则还支持HTTP/2.0协议,HTTP/2.0的处理与HTTP/1.1AJP不同,采用一种升级协议的方式实现。

  • HTTP/1.1协议:大家最熟悉的协议了,绝大多数web应用采用的访问协议,Tomcat既是Servlet容器又是HTTP服务器,单独运行就可以对外提供服务,但是一般会搭配Nginxweb服务器做反向代理和负载均衡。

  • HTTP/2.0协议:自Tomcat8.5开始支持,相较于HTTP/1.1采用二进制传输数据而非文本格式;对消息头采用HPACK压缩,提升传输效率;基于帧和流的多路复用,真正实现了基于一个连接多请求并发处理;支持服务器主动推送。

  • AJP/1.3协议:全名Apache JServ Protocol,是Alexei Kosut创建的定向包通信协议,采用二进制格式传输可读文本。用于集成Web服务器,以提升静态资源的访问性能,当前最新版本为1.3。目前ApacheTomcatNginxJettyJBoss等均已支持AJP。(名不见经传,不过多解释)

除了支持3种协议外,还分别支持3种I/O方式:NIONIO2APR,Tomcat8.5之前默认还支持BIO,后来因为性能问题直接给删除了,APR也贴上了过期标签。协议和I/O方式两两组合就出现了很多实现类:Http11NioProtocolHttp11Nio2ProtocolHttp11AprProtocol(已过期)、AjpNioProtocolAjpNio2ProtocolAjpAjpProtocol(已过期)。(HTTP/2.0是在HTTP/1.1的基础上升级处理的,不在该继承体系内,APR采用Apache可移植运行库(c++编写的本地库,就是native方法)实现的,官方已标注过期不建议使用,所以不过多解释)

rotocolHandler继承关系

Tomcat采用UpgradeProtocol表示HTTP升级协议,当前只有一个实现类Http2Protocol用于处理HTTP/2.0。它根据请求创建一个用于升级处理的令牌UpgradeToken,该令牌包含了具体的HTTP升级处理器HttpUpgradeHandlerHTTP/2.0的处理器为Http2UpgradeHandler)。(Tomcat中WebSocket也是通过UpgradeToken机制实现的,其处理器为WsHttpUpgradeHandler

1、Endpoint通信端点

Endpoint负责网络通信,监听一个端口,循环接收socket请求,读取网络字节流等。Endpoint不是接口,而是提供了一个抽象类AbstractEndpoint,又根据I/O方式提供了若干实现类:

AbstractEndpoint

Endpoint继承关系

网络通信这一层是非常抽象的,传输层协议毋庸置疑是TCP/IP,但是如何监听socket请求,读取网络字节流的方式是多样的,同步非阻塞、I/O多路复用、异步非阻塞等等:

  • Endpoint高度抽象出一个Acceptor来循环监听socket请求;

  • Tomcat是支持高并发的,但是机器的性能是有限的,为了保证Web服务器不被高流量冲垮,所以在接收请求前会有一个LimitLatch限流器(利用AQS实现);

  • 接收到的socket通道(SocketChannel or AsynchronousSocketChannel),会先根据I/O方式包装一下,如同步非阻塞NioChannel、异步非阻塞Nio2Channel等;

  • 包装之后的socket通道又用一个更抽象的SocketWrapper封装,以应对不同方式的网络字节流的读取和写入;

  • 出于高并发的设计,将抽象的SocketWrapper交由SocketProcessor任务对象处理,SocketProcessor会扔进一个线程池Executor处理;

  • 为了进一步提高性能,每次处理请求都会把一些对象缓存起来,不重复创建,比如SocketWrapperSocketProcessor等。

Endpoint结构

2、Processor应用层协议解析

Acceptor接收到请求封装成一个SocketProcessor扔进线程池Executor后,会调用Processor从操作系统底层读取、过滤字节流,对应用层协议(HTTP/AJP)进行解析封装,生成org.apache.coyote.Requestorg.apache.coyote.Response对象。不同的协议有不同的ProcessorHTTP/1.1对应Http11ProcessorAJP对应AjpProcessorHTTP/1.2对应StreamProcessorUpgradeProcessorInternalUpgradeProcessorExternal用于协议升级:

Processor继承关系

(1)ConnectionHandler创建合适的Processor

SocketProcessor并不是直接调用的Processor,而是通过org.apache.coyote.AbstractProtocol.ConnectionHandler#process找到一个合适的Processor进行请求处理:

  • 根据不同协议创建Http11Processor or AjpProcessor

  • 根据协议升级是内部升级(HTTP/2.0)还是外部升级创建UpgradeProcessorInternal or UpgradeProcessorExternal

(2)协议升级

如果是正常的协议,如HTTP/1.1AJP/1.3,则Processor#process处理完请求后会直接调用Adapter#service,将请求转发给Container

如果是协议升级(除Websocket),首先通过HTTP/1.1进行协议升级:

  • 服务器接收到带有特殊请求头(Upgrade)的HTPP/1.1连接,因此仍会先交给Http11Processor进行处理;

  • 根据请求头Upgrade对应协议名创建 UpgradeToken,并赋值给当前Processor

  • 返回SocketState.UPGRADING,再由ConnectionHandler进行协议升级;

  • ConnectionHandler会从当前Processor获取UpgradeToken对象(如果没有,则默认为HTTP/2.0),并构建一个升级的Processer(若为Tomcat可以处理的协议升级(HTTP/2.0WebSocket) ,则是UpgradeProcessorInternal,否则为UpgradeProcessorExternal)。

  • 替换当前Processer,并将当前Processer释放回收;

  • UpgradeProcessor 设置给 UpgradeToken中的HttpUpgradeHandler ,并调用HttpUpgradeHandler.init进行初始化,开启升级协议的处理。

  • 由于HTTP/2.0是多路复用协议,一个连接可以处理多个HTTP请求,所以对于Http2UpgradeHandler,会将每次请求响应交于StreamProcessor处理,再由StreamProcessor将请求提交给Container

注意:

  • UpgradeProcessorInternalUpgradeProcessorExternal都实现了接口WebConnection,表示一个用于升级的连接,并不处理协议升级后数据读写和解析,而是交由HttpUpgradeHandler,对于Http2UpgradeHandler再构建StreamProcessor,又将StreamProcessor包装成任务类StreamRunnable,扔进线程池Executor处理。

  • WebSocket也属于协议升级,和HTTP/2.0升级方案一致,但是协议升级的判断机制有所不同,WebSocket升级判断不在连接器里,而是交由Servlet容器通过当前请求的过滤器WsFilter判断,如果是WebSocket协议升级,则调用当前org.apache.catalina.connector.Request#upgrade构建UpgradeToken并传递给Http11Processor处理(调用钩子函数org.apache.coyote.AbstractProcessor#action),之后到了ConnectionHandler逻辑就跟HTTP/2.0升级差不多了。

3、配置方式

<Connector port=“8080” protocol=“HTTP/1.1”

connectionTimeout=“20000”

executor=“tomcatThreadPool”

redirectPort=“8443”>

  • portConnector监听的端口。

  • protocol是应用层协议名,可填参数有HTTP/1.1org.apache.coyote.http11.Http11NioProtocolAJP/1.3org.apache.coyote.ajp.AjpNioProtocol,如果protocol不填,则默认为Http11NioProtocol

  • connectionTimeout表示Connector接收到连接后等待超时时间,单位毫秒,默认20秒。

  • executor表示使用一个共享线程池,若使用私有线程池,则executor不需要指定,私有线程池可选参数有minSpareThreads=“10”maxThreads=“200”

  • redirectPort表示非SSL重定向到SSL端口,当请求是non-SSL请求,但是接收到的请求内容需要SSL传输,则重定向到SSL端口。

  • 若为HTTP开启HTTP/2.0支持,需要配置UpgradeProtocol

孤独而又灿烂的神

四、Adapter


Adapter接口只有一个实现类org.apache.catalina.connector.CoyoteAdapter,其主要职责如下:

  • org.apache.coyote.Requestorg.apache.coyote.Response转为实现了标准Servletorg.apache.catalina.connector.Requestorg.apache.catalina.connector.Response

  • 将请求体的serverNameURIversion传给Mapper组件做映射,匹配到合适的HostContextWrapper

  • RequestResponse传给Container处理,Engine通过管道Pipeline传给HostHost再传给ContextContext再传给WrapperWrapper是最终的Servlet

五、请求处理完整流程

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

最后

作为过来人,小编是整理了很多进阶架构视频资料、面试文档以及PDF的学习资料,针对上面一套系统大纲小编也有对应的相关进阶架构视频资料


链图片转存中…(img-ZgIkENqr-1711008761495)]

最后

作为过来人,小编是整理了很多进阶架构视频资料、面试文档以及PDF的学习资料,针对上面一套系统大纲小编也有对应的相关进阶架构视频资料

[外链图片转存中…(img-IVsSc5CB-1711008761495)]
[外链图片转存中…(img-gniHBnZV-1711008761496)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 23
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值