首先摘自我的好友。傻博语录:人生就是悲剧
上次说到每一个请求会分配给一个Worker处理,而Worker与我们平时写代码都是围绕Servlet写的,到底又有些什么差别呢?
worker后面是委托给Handler处理的。
handler处理的时候分配给Http11Processor(Http11Processor被维护在一个先进先出队列当中)。
而所有的HttpProcessor共享Http11Protocal 的Adapter成员变量,Adapter会调用到Servlet,即所有Handler都用同一个Adapter。
首先请看图:
讲述下每个部分的作用:
JioEndPointer:启动一个线程监听socket,并把到来的请求分配给相应的worker
Http11ConnectionHandler: Http协议的基于普通IO的处理方式.
Adapter:Http协议的请求 委托或 适配给 servlet容器处理的适配器
attributes:Http协议的相关属性设置
其中的对应关系也非常重要:
A,1个worker 必须对应一个 Http11ConnectionHandler 中的Http11ConnectionProcessor(是handler里面真正处理的Http协议的类)
B,所有的worker都持有同一个Adapter
详细类图下图所示:
我在HttpServlet的service方法里设置了一个断点,然后调试了下,可以看一下调用栈。
调用栈很清晰得说明了调用到哪些类和顺序:也可以看官方化得时序图:
http://tomcat.apache.org/tomcat-6.0-doc/architecture/requestProcess/requestProcess.pdf
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是线程安全的。
- 大小: 101.1 KB
- 大小: 136.9 KB
- 大小: 21.9 KB
- 大小: 100.1 KB
分享到:
相关推荐
NULL 博文链接:https://yjhexy.iteye.com/blog/661491
NULL 博文链接:https://yjhexy.iteye.com/blog/668334
tomcat中server配置文件的结构,以及处理一个http请求的全过程
Tomcat请求访问流程(逻辑).vsdx
tomcat工作原理深入详解——HowTomcatWorks中文版.pdf
tomcat GET请求与POST请求
3-5Tomcat响应请求源码与nio处理请求源码实现.mp4
IIS 7.5 以下版本不支持多域名共用443端口 SSL 服务,采用nginx 单独处理来自443端口的请求,从而实现多域名 SSL 附件包含,图文设置nginx, nginx免安装包,可直接使用,已支持SNI(Server Name Indication)
Tomcat怎样防止跨站请求伪造(CSRF) 1
解决跨域发送请求,跨域请求资源的问题。
Tomcat处理请求.vsdx
主要介绍了从连接器组件看Tomcat的线程模型——BIO模式,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
100——客户必须继续发出请求 101——客户要求服务器根据请求转换HTTP协议版本 200——交易成功 201——提示知道新文件的URL 202——接受和处理、但处理未完成 203——返回信息不确定或不完整 204——请求收到,但...
异常:Invalid character found in the request target.... connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" relaxedPathChars="[]{}|\\^" relaxedQueryChars="[]{}|\\^" />
在Linux服务器中部署tomcat应用
Tomcat6.0压缩包资源下载Tomcat6.0压缩包资源下载Tomcat6.0压缩包资源下载Tomcat6.0压缩包资源下载
https生成jks与配置tomcat等操作。生成cer 生成服务端文件与客户端文件