05 | Tomcat系统架构(上): 连接器是如何设计的?
该思维导图由 AI 生成,仅供参考
Tomcat 总体架构
- 深入了解
- 翻译
- 解释
- 总结
Tomcat连接器设计复杂,通过连接器和容器实现Socket连接和Servlet管理功能。支持多种I/O模型和应用层协议,如NIO、APR、HTTP/1.1、AJP和HTTP/2。连接器模块包括Endpoint、Processor和Adapter,实现网络通信、协议解析和Request/Response处理。通过抽象接口和模块化设计,实现高内聚、低耦合,封装变化,增加复用性。连接器的组件图清晰展示了继承和层次关系。整体设计体现了Tomcat连接器的灵活性和扩展性,为深入学习Tomcat工作原理提供基础。
《深入拆解 Tomcat & Jetty 》,新⼈⾸单¥68
全部留言(124)
- 最新
- 精选
- 电光火石对Tomcat的结构有个清晰的了解,其中有两个问题: 1. PorotocolHandler的继承关系是不是太重了,看起来像典型的多维度扩展,nio2在apj和1HTTP11都要做一遍,用组合会不会更好 2. 为什么要多一层adapter,在processor直接转换为容器的servletrequest和servletresponse不是更好,为什么要先转化Tomcat的request和response,再用adapter做一层转换消耗性能? 谢谢了!
作者回复: 1,说的对,能用组合就不用继承,这里我感觉Tomcat设计者考虑的是通过多层继承来尽量重用一些通用的逻辑。另外I/O模型和应用层协议的个数也是可控的,用户可以在server.xml中直接指定想要的连接器类型:比如Http11NioProtocol和Http11Nio2Protocol。 2,这里的考虑是,如果连接器直接创建ServletRequest和ServletResponse对象的话,就和Servlet协议耦合了,设计者认为连接器尽量保持独立性,它不一定要跟Servlet容器工作的。另外对象转化的性能消耗还是比较少的,Tomcat对HTTP请求体采取了延迟解析的策略,也就是说,TomcatRequest对象转化成ServletRequest的时候,请求体的内容都还没读取呢,直到容器处理这个请求的时候才读取的。
2019-05-218166 - 锦两个问题请教一下老师 第一,如何debug源码呢? 第二,tomcat和netty有什么区别呢?为什么netty常常用做底层通讯模块,而tomcat作为web容器呢?
作者回复: 1)软件系统本质是对信息的处理,要跟踪信息在流动过程中的经过的关键环节,并在这些地方下断点,看看变量的值是什么。比如你可以在业务代码中下个断点,看看调用栈,看Tomcat和Spring是怎么调到你的代码的,然后在这个调用栈中的关键函数里上下都看看,先熟悉个大概,然后带着问题去深入调试。 2)你可以把Netty理解成Tomcat中的连接器,它们都负责网络通信,都利用了Java NIO非阻塞特性。但Netty素以高性能高并发著称,为什么Tomcat不把连接器替换成Netty呢?第一个原因是Tomcat的连接器性能已经足够好了,同样是Java NIO编程,套路都差不多。第二个原因是Tomcat做为Web容器,需要考虑到Servlet规范,Servlet规范规定了对HTTP Body的读写是阻塞的,因此即使用到了Netty,也不能充分发挥它的优势。所以Netty一般用在非HTTP协议和Servlet的场景下。
2019-05-2112114 - 喆“EndPoint 是通信端点,即通信监听的接口,是具体的 Socket 接收和发送处理器,是对传输层的抽象,因此 EndPoint 是用来实现 TCP/IP 协议的。”,【EndPoint是用来实现TCP/IP协议的】这个没有太明白,据我有限的知识所知,TCP/IP协议是【由操作系统实现】的,而socket只是在TCP/IP之上展现给用户层的一个接口,而EndPoint又用到了socket接口(我瞎猜的)。所以,我是否可以把这句话理解为,EndPoint利用Socket接口来将底层传来的数据转化成为HTTP格式的数据,这种行为就可以看作是对TCP/IP协议的一种间接实现。
作者回复: 理解正确👍
2019-05-22361 - ty_young老师,我看您说socket = endpoint.serverSocketAccept()这个是阻塞式accept;但是连接器使用的IO模型是NIO或者AIO啊,都是非阻塞的吧,只是同步或者非同步的区别吧
作者回复: 阻塞和非阻塞说的是线程发起IO操作时,如果数据没有就绪,线程是否挂起。 同步异步说的是,应用程序与内核交互时,数据从内核空间到用户空间的拷贝,是内核主动发起还是由应用程序来触发,14篇会详细介绍。 这里的accept调用,当连接请求未到时,应用线程会挂起,因此是阻塞的,但为什么又说NIO是非阻塞呢?这是因为读取数据的线程没有挂起,因为之前已经通过Selector侦测到数据已经准备好了,到了内核空间,数据读取线程不需要等待,不需要挂起去等待数据。
2019-06-07349 - 郑晨Cc老师有个问题想请教: tomcat既然已经使用了java的nio模型 而nio模型在linx上是基于epoll 实现的 那为什么和同样的使用epoll的nginx相比 他对于http请求处理的性能远不如nginx呢
作者回复: Nginx/Apche一般做反向代理和处理静态HTML资源,做的事情相对来说简单,KPI就是要快,因此用C语言实现,直接调用操作系统API,充分利用操作系统的高级特性。 而Tomcat用来处理动态请求,还需要跑Java应用,因此用Java实现,因此”快“不是它主要的KPI。Java调用操作系统API要通过JNI,无形中有性能损耗。另外Tomcat通过使用Apache APR本地库来做I/O通信,性能已经跟Apache、Nginx接近了。
2019-05-31344 - zhycareer老师,源码如何阅读效果好啊?现在源码一大堆,不知从何下手。谢谢
作者回复: 抓主线,抓主干,每个系统中都有一个关键的核心类,紧紧抓住这些类,先不要分散,在逐步看旁枝,等你学习弄明白一个经典的系统,很多套路你就明白了。
2019-05-21330 - 易儿易这个专栏期待已久,一出立马就订阅了,但是因为其他课程没结束,导致这个课程没有跟上老师的节奏,目前正在努力追赶,我订阅了不少课程,李号双老师是回答问题最详细最用心的一个没有之一,虽然我还没来得及提一个问题,但是已经从老师给其他学生的回复中学习了不少……给老师点赞!!!
作者回复: 谢谢😄
2019-06-2924 - 欠债太多io是盲区啊,老师有什么建议呢
作者回复: unix环境高级编程里相关章节有详细介绍,这个专栏也会图文并貌分析,你有没有发现这个专栏的内容其实蛮容易懂的😊
2019-05-2124 - 鱼乐老师,有个问题,根据网络协议分层模型,请求不应该是先经过Http协议,然后才经过TCP协议处理的吗,上面的图处理顺序感觉反了
作者回复: 发送方是先http数据生成后tcp发送,接收方先tcp接收,再http解析
2019-06-27319 - 学无涯一个service对应tomcat中部署的一个项目,一个连接器对应一个请求,这样理解对吗
作者回复: 一个Service中可以部署多个项目呢,一个连接器对应一个监听端口,不是一个请求,一个端口上可以接收多个请求。
2019-05-21319