设为首页 收藏本站
查看: 467|回复: 0

[经验分享] tomcat源码分析之connector

[复制链接]

尚未签到

发表于 2017-1-23 09:17:54 | 显示全部楼层 |阅读模式
最近看了tomcat的源码,想写点总结。

tomcat的模块划分可以用下面的图视之:
DSC0000.jpg
从上面的图可以看出,在客户端访问tomcat的时候有一层叫做connector的东西,这其实是处理来自于客户端的协议,左边的coyote connector是对HTTP/1.1协议处理,右边的jk connector是对AJP/1.3协议做处理。

以下就针对coyote connector做一下源代码分析。

首先我们看两个相关的类图:
DSC0001.jpg
DSC0002.jpg
对上面的类图做一下简单说明:
JIoEndpoint:提供监听线程Acceptor接受socket并且创建一个新的Worker线程处理connection,处理完放入WorkerStack。
WorkerStack:含有一个存放Worker线程的数组。
Acceptor:Server socket acceptor thread。
Worker:线程类,并调用Http11ConnectionHandler处理socket。
Executor:执行线程,线程作为参数传入
SocketProcessor:线程类,类似于Worker,也是调用Http11ConnectionHandler处理socket。
Http11Processor:真正的Processes HTTP requests类。涉及到http协议中一些参数的实现,比如长连接。并且继承了ActionHook,可以对ActionCode代表的事件做相应的处理,即修改http协议中的参数。
Http11ConnectionHandler:从队列ConcurrentLinkedQueue<Http11Processor>中取出Http11Processor对socket处理。
Http11Protocol:继承了ProtocolHandler,是处理协议的总的处理器。从名字就可以看出这一点。其实例变量包括Http11ConnectionHandler,JIoEndpoint,ServerSocketFactory,SSLImplementation,Adapter,有两个重要的方法init()和start(),就是初始化和启动的方法。

下面看几个流程图。

先看一下tomcat启动时的load流程:
DSC0003.jpg
tomcat启动时的load从Bootstrap这个类的load方法开始,一步一步的初始化,在初始化Http11Protocol的时候会把Http11ConnectionHandler注入到JIoEndpoint,并调用JIoEndpoint的初始化方法,就是用DefaultServerSocketFactory去创建ServerSocket。

再来看tomcat启动时的start流程:
DSC0004.jpg
tomcat启动时的start从是紧接着上面的load,load完后从Bootstrap这个类的start开始一步一步的start,在Http11Protocol调用start的时候会调用JIoEndpoint的start方法,这个方法会new一个WorkerStack,并会new一个Acceptor线程,放入到Thread中,用Thread的start方法启动线程。

下面看一下上面启动的线程里如何运作,Acceptor线程其实是一个循环接受socket的类,我们还是来看一下流程图:
DSC0005.jpg
在Acceptor线程的run方法里,对每一个socket会产生一个Worker线程,在启动这个Worker线程后,这个线程的run方法会调用await方法其实是先让这个线程处于wait状态。再说上面的Acceptor线程这时会调用assign方法,其实是用notifyAll()去解开Worker线程的wait状态。当然由于是线程并没有一定的先后,以上也许是先assign,后await也有可能,这时就不会产生wait状态了。在处理完socket后,会把此Worker线程回收到WorkerStack中,下次可以从其中拿而不用新创建,但是当很多请求的时候,Worker不够用了,也需要创建新的Worker线程。WorkerStack中Worker数组的最大值默认是200。
由于Worker线程中的run方法是处在一个不断的循环中,当下一次循环的时候又将进入wait状态,等待唤醒。因此在WorkerStack中的Worker线程就是一个个处于wait状态的线程。
以上的这种请求处理方式就是用一个线程循环的去接受,再创建线程或从线程数组中获取线程去处理请求。
其实tomcat可以配置线程池的,在代码中也是这样判断的:如果没有线程池就创建WorkerStack,后面用Worker线程处理socket;如果有线程池时就使用线程池,看代码executor.execute(new SocketProcessor(socket));就是创建一个SocketProcessor线程去处理socket,SocketProcessor中的run方法和Worker线程类似,只是不循环,也不回收。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-332311-1-1.html 上篇帖子: Tomcat server.xml 文件 下篇帖子: 把tomcat配置成服务
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表