• 电光火石
    2019-05-21
    对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的时候,请求体的内容都还没读取呢,直到容器处理这个请求的时候才读取的。

     1
     66
  • 锦
    2019-05-21
    两个问题请教一下老师
    第一,如何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的场景下。

    
     30
  • 喆
    2019-05-22
    “EndPoint 是通信端点,即通信监听的接口,是具体的 Socket 接收和发送处理器,是对传输层的抽象,因此 EndPoint 是用来实现 TCP/IP 协议的。”,【EndPoint是用来实现TCP/IP协议的】这个没有太明白,据我有限的知识所知,TCP/IP协议是【由操作系统实现】的,而socket只是在TCP/IP之上展现给用户层的一个接口,而EndPoint又用到了socket接口(我瞎猜的)。所以,我是否可以把这句话理解为,EndPoint利用Socket接口来将底层传来的数据转化成为HTTP格式的数据,这种行为就可以看作是对TCP/IP协议的一种间接实现。

    作者回复: 理解正确👍

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

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

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

    
     16
  • 郑晨Cc
    2019-05-31
    老师有个问题想请教: 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接近了。

    
     11
  • zhycareer
    2019-05-21
    老师,源码如何阅读效果好啊?现在源码一大堆,不知从何下手。谢谢

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

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

    作者回复: 谢谢😄

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

    作者回复: 对的

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

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

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

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

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

    作者回复: 是的

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
     3
我们在线,来聊聊吧