深入拆解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
登录|注册

13 | 热点问题答疑(1):如何学习源码?

李号双 2019-06-08
不知道你有没有留意到,不少高端开发岗位在招聘要求里往往会写这么一条:研究过框架和中间件源码的优先考虑。这是因为一切秘密都藏在源码之中,阅读源码会让我们对框架或者中间件的理解更加深刻。有时候即使你阅读了大量原理性的文档,但如果不看源码,可能仍然会觉得还没有理解透。另外如果你能深入源码,招聘者从侧面也能感觉到你的学习热情和探索精神。
今天我们就来聊聊源码学习这个话题。对于 Java 后端开发来说,有不少经典的开源框架和中间件,下面我帮你按照后端的分层架构整理出来供你参考。
服务接入层:反向代理 Nginx;API 网关 Node.js。
业务逻辑层:Web 容器 Tomcat、Jetty;应用层框架 Spring、Spring MVC 和 Spring Boot;ORM 框架 MyBatis;
数据缓存层:内存数据库 Redis;消息中间件 Kafka。
数据存储层:关系型数据库 MySQL;非关系型数据库 MongoDB;文件存储 HDFS;搜索分析引擎 Elasticsearch。
这其中每一层都要支持水平扩展和高可用,比如业务层普遍采用微服务架构,微服务之间需要互相调用,于是就出现了 RPC 框架:Spring Cloud 和 Dubbo。
除此之外,还有两个非常重要的基础组件:Netty 和 ZooKeeper,其中 Netty 用于网络通信,ZooKeeper 用于分布式协调。其实很多中间件都用到了这两个基础组件,并且 ZooKeeper 的网络通信模块也是通过 Netty 来实现的。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入拆解Tomcat & Jetty 》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(17)

  • Dovelol
    老师好,想请教下tomcat中有个名叫Catalina-utility-xx线程作用是什么呢?能否讲下tomcat中各种线程池或者线程的作用?

    作者回复: 名字里带有Acceptor的线程负责接收浏览器的连接请求。

    名字里带有Poller的线程,其实内部是个Selector,负责侦测IO事件。

    名字里带有Catalina-exec的是工作线程,负责处理请求。

    名字里带有 Catalina-utility的是Tomcat中的工具线程,主要是干杂活,比如在后台定期检查Session是否过期、定期检查Web应用是否更新(热部署热加载)、检查异步Servlet的连接是否过期等等。

    2019-06-09
    3
    17
  • -W.LI-
    谢谢老师!少走好多弯路
    2019-06-08
    9
  • 海水
    老师好,如果向spring controler里面的耗时避免不了,比如三方接口的耗时避免不了秒级的耗时,这样是不是要用异步servlet,耗时交给单独的线程池?但是我感觉这样即使用单独的线程池也是用的系统的级线程池,高并发的话是不是也解决不了问题?有没有办法换成协程来解决问题?但是spring 貌似又是线程级的,这种场景是不是 改用go会好点?

    作者回复: 如果业务处理时间过长,阻塞大量Tomcat线程导致线程饥饿,可以考虑异步Servlet,这样Tomcat线程立即返回,耗时处理由业务线程来处理。

    但业务线程同样有线程阻塞的问题,比如阻塞在IO上。基本思路都是用“异步回调”来避免阻塞,采用异步非阻塞IO模型,用少量线程通过事件循环来提高吞吐量。Spring给出的方案是Spring Webflux。Nodejs也是这样,适合IO密集型的应用。

    协程也是这个思路,并且它的网络通信也是通过epoll来实现非阻塞的,只不过它向开发者提供了“同步阻塞”式的API,另外协程的上下文切换开销也比线程小,因为它将“函数调用上下文”保存在应用层面,内核感觉不到,但是这需要额外的内存、调度和管理开销。

    2019-06-08
    7
  • Monday
    个人感觉,学习知识能问出高质量问题非常重要,感谢老师的问题和源码学习路线。🙏🙏🙏
    2019-06-08
    6
  • Vincent
    老师好,"包括静态的依赖关系和动态的协作关系" 能通过Tomcat 具体讲解下吗

    作者回复: Connector组件中持有ProtocolHandler和Processor实例,这算是静态的依赖关系;而Connector将请求解析出来后交给Container处理,这是动态的协作关系。说的有点咬文嚼字:)

    2019-07-09
    3
  • Dovelol
    老师好,之前请教了tomcat中的几种线程,有个小问题是,我在controller中调用Thread.currentThread()发现有些项目(可能是不同项目或者不同运行环境)确实是Catalina-exec在处理请求,但是有些名称是Thread-1,Thread-2这种线程在处理,区别在哪呢,是不是哪个地方配置不同的原因?

    作者回复: 默认情况下是一个Connector一个线程池,你还可以在server.xml中配置一个全局线程池,还可以指定线程名字的前缀:

    <Service name="Catalina">
        <!--The connectors can use a shared executor, you can define one or more named thread pools-->
        <!--
        <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="150" minSpareThreads="4"/>
        -->

    2019-06-11
    2
  • 发条橙子 。
    老师 , 那你的意思是不是 ,其实现在已经把tomcat的整体架构讲完了 。我们可以先试着自己去读源码了?

    作者回复: 对的尤其是接下来的文章会深入细节,我会贴出关键代码和分析,但课后最好也去读读相关源码。

    2019-06-09
    2
  • QQ怪
    谢谢老师分享
    2019-06-08
    1
  • ty_young
    老师,您说的服务端线程模型就是Proactor和Reactor么

    作者回复: 对的

    2019-06-08
    1
  • 尹兆发
    老师辛苦了
    2019-06-08
    1
  • 苏忆
    谢谢老师
    2019-09-27
  • 仙道
    能不能教下怎么把tomcat源码导入idea啊
    2019-07-09
    3
  • 唐木儿
    老师,我下载了Tomcat源码后,用Ant编译后,显示"程序包org.apache.tools.Ant不存在",是怎么回事呢?直接通过CMD,键入"ant",提示的是BUILD SUCCESS!这表示已经编译过了吧?但是一运行就显示上面的提示"程序包org.apache.tools.Ant不存在"

    作者回复: 建议还是不要折腾Ant编译了,直接用内嵌式方式启动和调试。

    2019-06-17
    1
  • 幸运
    老师!您好! 可以问你一个开发中遇到的问题吗?就是我的项目在eclipse中运行时接收数据没有出现乱码.但是把项目打war包导Tomcat中跑时接收数据就出现乱码,然后我在Tomcat-->catalina.bat文件中 添加 set JAVA_OPTS=-Dfile.encoding=UTF-8 这个,发现接收到的数据不乱码了?但是我用log4j打印的日志出现了乱码?这个问题我想请教一下?谢谢指点,查阅很多资料,实在没办法😣

    作者回复: file.encoding设成utf-8能解决输入数据乱码的问题,说明你的操作系统的默认字符集不是utf-8。

    log4j乱码需要看看log4j的配置文件里的配置的字符集是不是utf-8,还需要看看日志文件本身的格式是不是utf-8。

    2019-06-12
  • Joker
    谢谢老师。。。
    2019-06-12
  • Dovelol
    老师好,请教下,在看tomcat接收请求的源码时发现org.apache.coyote.Request在AbstractProcessor类中是一个成员变量,并且AbstractProcessor的实现类Http11AprProtocol是由recycledProcessors.pop()产生的,那所有请求岂不是公用一个Http11AprProtocol对象,那并发请求的时候Request对象的属性到底是哪个请求数据的呢,感觉Request对象应该是线程绑定的才对,但是没有找到绑定的地方。

    作者回复:
    一个请求到来,Tomcat会创建一个SocketProccessor,这是个runnable,会被扔到线程池执行。

    在执行过程中,会创建一个Request对象,一个Response对象,和一个Http11Processor对象(AbstractProcessor的子类)。
    一次请求处理完了,这些对象会被回收保存起来,重复使用(对象池技术)。

    建议看第14篇,有详细过程。

    2019-06-11
    1
  • imsunv
    老师关于网络通信的总结很棒,很多东西都是知道些,但是不能很好的总结下来
    2019-06-10
收起评论
17
返回
顶部