深入拆解 Tomcat & Jetty
李号双
eBay 技术主管
38890 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 45 讲
开篇词 (1讲)
深入拆解 Tomcat & Jetty
15
15
1.0x
00:00/00:00
登录|注册

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

反射和类加载技术
多线程
网络编程
ZooKeeper
Netty
RPC框架Spring Cloud、Dubbo
搜索分析引擎Elasticsearch
文件存储HDFS
非关系型数据库MongoDB
关系型数据库MySQL
消息中间件Kafka
内存数据库Redis
ORM框架MyBatis
应用层框架Spring、Spring MVC、Spring Boot
Web容器Tomcat、Jetty
API网关Node.js
反向代理Nginx
分享收获
提问和讨论
技术水平成长
学习新系统的便利性
理解透彻一个中间件
实践和摸索
参考官方文档和博客
记录学习成果
带着问题学习源码
源码调试
理解骨架类
弄清中间件核心功能
框架的通用性
通用技术应用
服务端线程模型
数据序列化
通信协议
I/O模型
积累通用技术
先学一些熟悉的或相对简单的
基础组件
微服务架构
数据存储层
数据缓存层
业务逻辑层
服务接入层
展示学习热情和探索精神
阅读源码加深对框架或中间件的理解
研究过框架和中间件源码的优先考虑
课后思考和分享
学习积累
学习源码方法
Java反射机制
网络通信
学习顺序建议
后端分层架构
高端开发岗位要求
如何学习源码?

该思维导图由 AI 生成,仅供参考

不知道你有没有留意到,不少高端开发岗位在招聘要求里往往会写这么一条:研究过框架和中间件源码的优先考虑。这是因为一切秘密都藏在源码之中,阅读源码会让我们对框架或者中间件的理解更加深刻。有时候即使你阅读了大量原理性的文档,但如果不看源码,可能仍然会觉得还没有理解透。另外如果你能深入源码,招聘者从侧面也能感觉到你的学习热情和探索精神。
今天我们就来聊聊源码学习这个话题。对于 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/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

学习源码对于高端开发岗位至关重要,因为源码中蕴含着一切秘密,阅读源码能够加深对框架或中间件的理解。对于Java后端开发者来说,学习经典的开源框架和中间件是必不可少的,如Nginx、Tomcat、Spring、MyBatis、Redis、Kafka等。在学习源码的过程中,需要掌握通用的技术,如网络编程、多线程、反射和类加载技术。学习源码的方法包括弄清楚中间件的核心功能、将源码跑起来并利用IDE的功能进行调试、带着问题去学习源码并记录所学内容。通过这些学习方法,可以更好地理解源码并树立攻克难关的信心。透彻理解一两个中间件后,积累的技术水平将使学习新系统变得更加轻松,能够快速理解其架构和角色关系,甚至发现改进的空间。若读者有疑问,可以在留言区提问,也欢迎分享课后思考和心得。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《深入拆解 Tomcat & Jetty 》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(22)

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

    作者回复: 名字里带有Acceptor的线程负责接收浏览器的连接请求。 名字里带有Poller的线程,其实内部是个Selector,负责侦测IO事件。 名字里带有Catalina-exec的是工作线程,负责处理请求。 名字里带有 Catalina-utility的是Tomcat中的工具线程,主要是干杂活,比如在后台定期检查Session是否过期、定期检查Web应用是否更新(热部署热加载)、检查异步Servlet的连接是否过期等等。

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

    作者回复: 如果业务处理时间过长,阻塞大量Tomcat线程导致线程饥饿,可以考虑异步Servlet,这样Tomcat线程立即返回,耗时处理由业务线程来处理。 但业务线程同样有线程阻塞的问题,比如阻塞在IO上。基本思路都是用“异步回调”来避免阻塞,采用异步非阻塞IO模型,用少量线程通过事件循环来提高吞吐量。Spring给出的方案是Spring Webflux。Nodejs也是这样,适合IO密集型的应用。 协程也是这个思路,并且它的网络通信也是通过epoll来实现非阻塞的,只不过它向开发者提供了“同步阻塞”式的API,另外协程的上下文切换开销也比线程小,因为它将“函数调用上下文”保存在应用层面,内核感觉不到,但是这需要额外的内存、调度和管理开销。

    2019-06-08
    2
    24
  • Vincent
    老师好,"包括静态的依赖关系和动态的协作关系" 能通过Tomcat 具体讲解下吗

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

    2019-07-09
    8
  • 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
    7
  • 发条橙子 。
    老师 , 那你的意思是不是 ,其实现在已经把tomcat的整体架构讲完了 。我们可以先试着自己去读源码了?

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

    2019-06-09
    7
  • 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
    2
    4
  • ty_young
    老师,您说的服务端线程模型就是Proactor和Reactor么

    作者回复: 对的

    2019-06-08
    2
  • 唐木儿
    老师,我下载了Tomcat源码后,用Ant编译后,显示"程序包org.apache.tools.Ant不存在",是怎么回事呢?直接通过CMD,键入"ant",提示的是BUILD SUCCESS!这表示已经编译过了吧?但是一运行就显示上面的提示"程序包org.apache.tools.Ant不存在"

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

    2019-06-17
    2
    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
    3
  • -W.LI-
    谢谢老师!少走好多弯路
    2019-06-08
    11
收起评论
显示
设置
留言
22
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部