13 | 热点问题答疑(1):如何学习源码?
该思维导图由 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-09572 - 海水老师好,如果向spring controler里面的耗时避免不了,比如三方接口的耗时避免不了秒级的耗时,这样是不是要用异步servlet,耗时交给单独的线程池?但是我感觉这样即使用单独的线程池也是用的系统的级线程池,高并发的话是不是也解决不了问题?有没有办法换成协程来解决问题?但是spring 貌似又是线程级的,这种场景是不是 改用go会好点?
作者回复: 如果业务处理时间过长,阻塞大量Tomcat线程导致线程饥饿,可以考虑异步Servlet,这样Tomcat线程立即返回,耗时处理由业务线程来处理。 但业务线程同样有线程阻塞的问题,比如阻塞在IO上。基本思路都是用“异步回调”来避免阻塞,采用异步非阻塞IO模型,用少量线程通过事件循环来提高吞吐量。Spring给出的方案是Spring Webflux。Nodejs也是这样,适合IO密集型的应用。 协程也是这个思路,并且它的网络通信也是通过epoll来实现非阻塞的,只不过它向开发者提供了“同步阻塞”式的API,另外协程的上下文切换开销也比线程小,因为它将“函数调用上下文”保存在应用层面,内核感觉不到,但是这需要额外的内存、调度和管理开销。
2019-06-08224 - Vincent老师好,"包括静态的依赖关系和动态的协作关系" 能通过Tomcat 具体讲解下吗
作者回复: Connector组件中持有ProtocolHandler和Processor实例,这算是静态的依赖关系;而Connector将请求解析出来后交给Container处理,这是动态的协作关系。说的有点咬文嚼字:)
2019-07-098 - 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-117 - 发条橙子 。老师 , 那你的意思是不是 ,其实现在已经把tomcat的整体架构讲完了 。我们可以先试着自己去读源码了?
作者回复: 对的尤其是接下来的文章会深入细节,我会贴出关键代码和分析,但课后最好也去读读相关源码。
2019-06-097 - Dovelol老师好,请教下,在看tomcat接收请求的源码时发现org.apache.coyote.Request在AbstractProcessor类中是一个成员变量,并且AbstractProcessor的实现类Http11AprProtocol是由recycledProcessors.pop()产生的,那所有请求岂不是公用一个Http11AprProtocol对象,那并发请求的时候Request对象的属性到底是哪个请求数据的呢,感觉Request对象应该是线程绑定的才对,但是没有找到绑定的地方。
作者回复: 一个请求到来,Tomcat会创建一个SocketProccessor,这是个runnable,会被扔到线程池执行。 在执行过程中,会创建一个Request对象,一个Response对象,和一个Http11Processor对象(AbstractProcessor的子类)。 一次请求处理完了,这些对象会被回收保存起来,重复使用(对象池技术)。 建议看第14篇,有详细过程。
2019-06-1124 - ty_young老师,您说的服务端线程模型就是Proactor和Reactor么
作者回复: 对的
2019-06-082 - 唐木儿老师,我下载了Tomcat源码后,用Ant编译后,显示"程序包org.apache.tools.Ant不存在",是怎么回事呢?直接通过CMD,键入"ant",提示的是BUILD SUCCESS!这表示已经编译过了吧?但是一运行就显示上面的提示"程序包org.apache.tools.Ant不存在"
作者回复: 建议还是不要折腾Ant编译了,直接用内嵌式方式启动和调试。
2019-06-1721 - 幸运老师!您好! 可以问你一个开发中遇到的问题吗?就是我的项目在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-123 - -W.LI-谢谢老师!少走好多弯路2019-06-0811