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

[经验分享] tomcat分配请求之——请求如何流程Connection

[复制链接]

尚未签到

发表于 2017-2-6 08:27:05 | 显示全部楼层 |阅读模式
  首先摘自我的好友。傻博语录:人生就是悲剧
  上次说到每一个请求会分配给一个Worker处理,而Worker与我们平时写代码都是围绕Servlet写的,到底又有些什么差别呢?
  worker后面是委托给Handler处理的。
  handler处理的时候分配给Http11Processor(Http11Processor被维护在一个先进先出队列当中)。
  而所有的HttpProcessor共享Http11Protocal 的Adapter成员变量,Adapter会调用到Servlet,即所有Handler都用同一个Adapter。
  首先请看图:
      
DSC0000.png
 讲述下每个部分的作用:




  JioEndPointer:启动一个线程监听socket,并把到来的请求分配给相应的worker
  Http11ConnectionHandler: Http协议的基于普通IO的处理方式.
  Adapter:Http协议的请求 委托或 适配给 servlet容器处理的适配器
  attributes:Http协议的相关属性设置
  
其中的对应关系也非常重要:
  A,1个worker 必须对应一个 Http11ConnectionHandler 中的Http11ConnectionProcessor(是handler里面真正处理的Http协议的类)
  B,所有的worker都持有同一个Adapter
  详细类图下图所示:
  
DSC0001.bmp
 
  我在HttpServlet的service方法里设置了一个断点,然后调试了下,可以看一下调用栈。 

DSC0002.png
  调用栈很清晰得说明了调用到哪些类和顺序:也可以看官方化得时序图: 
  http://tomcat.apache.org/tomcat-6.0-doc/architecture/requestProcess/requestProcess.pdf
  
DSC0003.png
  JIoEndpoint.java
  /** * Create (or allocate) and return an available processor for use in * processing a specific HTTP request, if possible. If the maximum * allowed processors have already been created and are in use, return * <code>null</code> instead. */ protected Worker createWorkerThread() { synchronized (workers) { if (workers.size() > 0) { curThreadsBusy++; return workers.pop(); } if ((maxThreads > 0) && (curThreads < maxThreads)) {              // 默认maxThreads 为200 curThreadsBusy++; if (curThreadsBusy == maxThreads) { log.info(sm.getString("endpoint.info.maxThreads", Integer.toString(maxThreads), address, Integer.toString(port))); } return (newWorkerThread()); } else { if (maxThreads < 0) { curThreadsBusy++; return (newWorkerThread()); } else { return (null); } } } } /** * Create and return a new processor suitable for processing HTTP * requests and returning the corresponding responses. */ protected Worker newWorkerThread() { Worker workerThread = new Worker(); workerThread.start(); return (workerThread); }


  从代码来看,如果没有到达请求最大值,首先会从栈中取得空闲的Worker,或者创建新的Worker。
  所以来一个请求,会分配给一个Worker,而Worker做了一些接收Socket,设置一些socket和需要的环境类,然后就交给了Servlet实例,而servlet实例启动的时候就是对于一个context 中配置的一个servlet只启动一个实例。
  StandardWrapper.java
  /** * Load and initialize an instance of this servlet, if there is not already * at least one initialized instance. This can be used, for example, to * load servlets that are marked in the deployment descriptor to be loaded * at server startup time. */ public synchronized Servlet loadServlet() throws ServletException { // Nothing to do if we already have an instance or an instance pool // 初始化servlet的时候,如果发现已经初始化完毕,则不再初始化 if (!singleThreadModel && (instance != null)) return instance;


  所以首先servlet不是线程安全的。
  其次 HttpSession不是线程安全的。
  还有 Context不是现成安全的。
  Request是线程安全的。

运维网声明 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-338018-1-1.html 上篇帖子: Birt部署在tomcat下的方法(转) 下篇帖子: tomcat 对静态资源的处理 —— Default Servlet
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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

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

扫描微信二维码查看详情

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


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


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


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



合作伙伴: 青云cloud

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