深入拆解Tomcat & Jetty
李号双
eBay技术主管
立即订阅
6067 人已学习
课程目录
已完结 44 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | Java程序员如何快速成长?
免费
模块一 必备基础 (4讲)
01 | Web容器学习路径
02 | HTTP协议必知必会
03 | 你应该知道的Servlet规范和Servlet容器
04 | 实战:纯手工打造和运行一个Servlet
模块二 整体架构 (9讲)
05 | Tomcat系统架构(上): 连接器是如何设计的?
06 | Tomcat系统架构(下):聊聊多层容器的设计
07 | Tomcat如何实现一键式启停?
08 | Tomcat的“高层们”都负责做什么?
09 | 比较:Jetty架构特点之Connector组件
10 | 比较:Jetty架构特点之Handler组件
11 | 总结:从Tomcat和Jetty中提炼组件化设计规范
12 | 实战:优化并提高Tomcat启动速度
13 | 热点问题答疑(1):如何学习源码?
模块三 连接器 (9讲)
14 | NioEndpoint组件:Tomcat如何实现非阻塞I/O?
15 | Nio2Endpoint组件:Tomcat如何实现异步I/O?
16 | AprEndpoint组件:Tomcat APR提高I/O性能的秘密
17 | Executor组件:Tomcat如何扩展Java线程池?
18 | 新特性:Tomcat如何支持WebSocket?
19 | 比较:Jetty的线程策略EatWhatYouKill
20 | 总结:Tomcat和Jetty中的对象池技术
21 | 总结:Tomcat和Jetty的高性能、高并发之道
22 | 热点问题答疑(2):内核如何阻塞与唤醒进程?
模块四 容器 (8讲)
23 | Host容器:Tomcat如何实现热部署和热加载?
24 | Context容器(上):Tomcat如何打破双亲委托机制?
25 | Context容器(中):Tomcat如何隔离Web应用?
26 | Context容器(下):Tomcat如何实现Servlet规范?
27 | 新特性:Tomcat如何支持异步Servlet?
28 | 新特性:Spring Boot如何使用内嵌式的Tomcat和Jetty?
29 | 比较:Jetty如何实现具有上下文信息的责任链?
30 | 热点问题答疑(3):Spring框架中的设计模式
模块五 通用组件 (4讲)
31 | Logger组件:Tomcat的日志框架及实战
32 | Manager组件:Tomcat的Session管理机制解析
33 | Cluster组件:Tomcat的集群通信原理
特别放送 | 如何持续保持对学习的兴趣?
模块六 性能优化 (8讲)
34 | JVM GC原理及调优的基本思路
35 | 如何监控Tomcat的性能?
36 | Tomcat I/O和线程池的并发调优
37 | Tomcat内存溢出的原因分析及调优
38 | Tomcat拒绝连接原因分析及网络优化
39 | Tomcat进程占用CPU过高怎么办?
40 | 谈谈Jetty性能调优的思路
41 | 热点问题答疑(4): Tomcat和Jetty有哪些不同?
结束语 (1讲)
结束语 | 静下心来,品味经典
深入拆解Tomcat & Jetty
登录|注册

05 | Tomcat系统架构(上): 连接器是如何设计的?

李号双 2019-05-21
在面试时我们可能经常被问到:你做的 XX 项目的架构是如何设计的,请讲一下实现的思路。对于面试官来说,可以通过你对复杂系统设计的理解,了解你的技术水平以及处理复杂问题的思路。
今天咱们就来一步一步分析 Tomcat 的设计思路,看看 Tomcat 的设计者们当时是怎么回答这个问题的。一方面我们可以学到 Tomcat 的总体架构,学会从宏观上怎么去设计一个复杂系统,怎么设计顶层模块,以及模块之间的关系;另一方面也为我们深入学习 Tomcat 的工作原理打下基础。

Tomcat 总体架构

我们知道如果要设计一个系统,首先是要了解需求。通过专栏前面的文章,我们已经了解了 Tomcat 要实现 2 个核心功能:
处理 Socket 连接,负责网络字节流与 Request 和 Response 对象的转化。
加载和管理 Servlet,以及具体处理 Request 请求。
因此 Tomcat 设计了两个核心组件连接器(Connector)和容器(Container)来分别做这两件事情。连接器负责对外交流,容器负责内部处理。
所以连接器和容器可以说是 Tomcat 架构里最重要的两部分,需要你花些精力理解清楚。这两部分内容我会分成两期,今天我来分析连接器是如何设计的,下一期我会介绍容器的设计。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入拆解Tomcat & Jetty 》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(88)

  • 电光火石
    对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-21
    1
    59
  • 两个问题请教一下老师
    第一,如何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-21
    26
  • “EndPoint 是通信端点,即通信监听的接口,是具体的 Socket 接收和发送处理器,是对传输层的抽象,因此 EndPoint 是用来实现 TCP/IP 协议的。”,【EndPoint是用来实现TCP/IP协议的】这个没有太明白,据我有限的知识所知,TCP/IP协议是【由操作系统实现】的,而socket只是在TCP/IP之上展现给用户层的一个接口,而EndPoint又用到了socket接口(我瞎猜的)。所以,我是否可以把这句话理解为,EndPoint利用Socket接口来将底层传来的数据转化成为HTTP格式的数据,这种行为就可以看作是对TCP/IP协议的一种间接实现。

    作者回复: 理解正确👍

    2019-05-22
    18
  • ty_young
    老师,我看您说socket = endpoint.serverSocketAccept()这个是阻塞式accept;但是连接器使用的IO模型是NIO或者AIO啊,都是非阻塞的吧,只是同步或者非同步的区别吧

    作者回复: 阻塞和非阻塞说的是线程发起IO操作时,如果数据没有就绪,线程是否挂起。
    同步异步说的是,应用程序与内核交互时,数据从内核空间到用户空间的拷贝,是内核主动发起还是由应用程序来触发,14篇会详细介绍。

    这里的accept调用,当连接请求未到时,应用线程会挂起,因此是阻塞的,但为什么又说NIO是非阻塞呢?这是因为读取数据的线程没有挂起,因为之前已经通过Selector侦测到数据已经准备好了,到了内核空间,数据读取线程不需要等待,不需要挂起去等待数据。

    2019-06-07
    13
  • 郑晨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-31
    9
  • zhycareer
    老师,源码如何阅读效果好啊?现在源码一大堆,不知从何下手。谢谢

    作者回复: 抓主线,抓主干,每个系统中都有一个关键的核心类,紧紧抓住这些类,先不要分散,在逐步看旁枝,等你学习弄明白一个经典的系统,很多套路你就明白了。

    2019-05-21
    7
  • 易儿易
    这个专栏期待已久,一出立马就订阅了,但是因为其他课程没结束,导致这个课程没有跟上老师的节奏,目前正在努力追赶,我订阅了不少课程,李号双老师是回答问题最详细最用心的一个没有之一,虽然我还没来得及提一个问题,但是已经从老师给其他学生的回复中学习了不少……给老师点赞!!!

    作者回复: 谢谢😄

    2019-06-29
    5
  • 永光
    老师,你看这样理解对不,
    采用何种I/O模式(NIO、NIO2、ARP),以及采用何种应用协议(HTTP1.1、AJP、HTTP/2)都是在processor这一层决定的。EndPoint只负责接收连接,并读取网络字节流但是不对字节流本身就进行任何解析。

    作者回复: 对的

    2019-06-05
    1
    5
  • 听雨
    一个service对应tomcat中部署的一个项目,一个连接器对应一个请求,这样理解对吗

    作者回复: 一个Service中可以部署多个项目呢,一个连接器对应一个监听端口,不是一个请求,一个端口上可以接收多个请求。

    2019-05-21
    1
    5
  • 新世界
    对tomcat的结构的连接器部分收获不少,有一问题,tomcat的endpoint的功能和netty的实现功能很多方面一样,tomcat为什么没有用netty作为底层通讯框架?

    作者回复: Tomcat在I/O模型和线程模型方面跟Netty很相似,后面会详细分析。

    2019-05-21
    5
  • -W.LI-
    老师好!Tomcat配置的并发数是文中endpoint里那个线程池么?IO方面知识比较薄弱,希望老师后期讲解时多花点心思。

    作者回复: 是的

    2019-05-21
    4
  • KL3
    您好,我不太理解io模型,是指若干个请求的网络字节流经过网络适配器,由连接器通过一个什么样的方式读到吗?
    我对io理解的不深,表达会有问题。

    作者回复: I/O是外部设备和主存之间拷贝数据的过程,I/O模型是实现这个过程的方式,后面会详细介绍各种I/O模型的区别:同步阻塞,同步非阻塞、异步等等。

    2019-05-21
    4
  • 鱼乐
    老师,有个问题,根据网络协议分层模型,请求不应该是先经过Http协议,然后才经过TCP协议处理的吗,上面的图处理顺序感觉反了

    作者回复: 发送方是先http数据生成后tcp发送,接收方先tcp接收,再http解析

    2019-06-27
    3
  • 西兹兹
    醍醐灌顶 以前学tomcat源码,关注的是类 方法,从来没这么清晰过
    2019-06-09
    3
  • 面白i小黄毛
    老师您好,"通过在 Tomcat 中配置多个 Service,可以实现通过不同的端口号来访问同一台机器上部署的不同应用。"这句话应该怎样理解?如果仅仅针对http来说的话,同一个tomcat可以设置多个端口号来启动多个应用吗?

    作者回复: 可以的,在server.xml配置多个service,或者同一个service里配置多个connector

    2019-05-27
    3
  • 王智
    老师您好,我有两个问题,
    一个是上面说到一个容器对接多个连接器,也就是service,这个具体是不是可以在tomcat的conf目录下的server.xml中发现呢? 但是一般情况下,也就是默认的,tomcat的一个server下只会有一个service组件,而connector就是在service组件中配置的呢?
    另一个是一个server中有一个或多个service,一个service中有多个连接器和一个容器,这里的容器到底是什么?我并没有在server.xml中找到相关的配置等呀.

    作者回复: 1.对的,默认是一个service
    2.容器就是装载Servlet的箱子,Tomcat的容器分层次,大箱子里有小箱子,最大的箱子是Engine,下一篇会讲到。

    2019-05-23
    3
  • allean
    可以理解为一个连接器对应一个应用吗

    作者回复: 不是的,一个连接器对应一个监听端口,比如一扇门,一个web应用是一个业务部门,进了这个门后你可以到各个业务部门去办事。

    2019-05-22
    3
  • 欠债太多
    io是盲区啊,老师有什么建议呢

    作者回复: unix环境高级编程里相关章节有详细介绍,这个专栏也会图文并貌分析,你有没有发现这个专栏的内容其实蛮容易懂的😊

    2019-05-21
    3
  • Adapter一层使用的是适配器设计模式,好处是当容器版本升级只修改Adaper组件适配到新版本容器就可以了,protocal handler组件代码不需要改动
    2019-05-21
    3
  • 老王的老李头
    看懂了,但是没有一个形象化的记忆点。

    作者回复: 😑后面还会有整体架构图。

    2019-05-21
    3
收起评论
88
返回
顶部