- 浏览: 147708 次
最新评论
-
zjhgx:
写的不错
tomcat架构分析 (Session管理) -
smallbug_vip:
very very good 如此好文章,一定要刷新一下最后评 ...
tomcat架构分析(概览) -
slightz:
楼主我已经深深的爱上你了
tomcat 性能之connector -
js_nicle:
受益匪浅,谢谢博主。
tomcat架构分析-索引 -
lianglaiyang:
楼主,什么时候给我们讲一下nio connector中的com ...
tomcat架构分析 (connector NIO 实现)
出处:http://gearever.iteye.com
源码面前,了无秘密
----侯捷
在tomcat架构分析(valve机制)(http://gearever.iteye.com/blog/1536022)里已经对valve的机制做了分析。现在通过源码来加深下理解。侯捷说过,源码面前,了无秘密。通过这些代码,可以看到在tomcat中我们经常碰到的一些现象或配置是怎么实现的。
StandardEngineValve
看一下StandardEngineValve的调用逻辑;
可以清晰的看到,根据request定位到可以处理的host对象,同时,开始从头调用host里的pipeline上的valve。
StandardHostValve
看一下StandardHostValve的调用逻辑;
可以清晰的看到,注释部分里根据request定位到可以处理的context对象,同时,开始从头调用context里的pipeline上的valve。在调用完context的所有的valve之后(当然也是context调用完其对应的wrapper上的所有valve之后),蓝色部分显示了拿到response对象时可以做的处理。
熟悉tomcat的可能有配置错误信息的经验,例如;
它就是为了在用户访问资源出现HTTP 404错误时,将访问重定向到一个统一的错误页面。这样做一是为了美观,另一个主要作用是不会将一些具体的错误信息例如java抛异常时的栈信息暴露给用户,主要还是出于安全的考虑。 上述代码中的注释部分就是实现这个重定向功能。
StandardContextValve
看一下StandardContextValve的调用逻辑;其代码比较多,只贴一些比较核心的吧。
可以清晰的看到,注释部分里根据request定位到可以处理的wrapper对象,同时,开始从头调用wrapper里的pipeline上的valve。 需要注意的是,这里在调用wrapper的valve前后,分别有响应request初始化及撤销事件的逻辑,tomcat有一整套事件触发体系,这里限于篇幅就不阐述了。有时间专门说。
StandardWrapperValve
看一下StandardWrapperValve的调用逻辑;其代码比较多,只贴一些比较核心的吧;
可以清晰的看到,注释部分里,先是能拿到相应的wrapper对象;然后完成加载wrapper对象中的servlet,例如如果是jsp,将完成jsp编译,然后加载servlet等;再然后,根据配置生成一个filter栈,通过执行栈,调用完所有的filter之后,就调用servlet,如果没有配置filter,就直接调用servlet,生成filter栈是通过request的URL模式匹配及servlet名称来实现的,具体涉及的东西在tomcat的servlet规范实现中再阐述吧。
以上,完成了一整套servlet调用的过程。通过上面的阐述,可以看见valve是个很灵活的机制,通过它可以实现很大的扩展。
Valve的应用及定制化
Tomcat除了提供上面提到的几个标准的valve实现外,也提供了一些用于调试程序的valve的实现。实现valve需要继承org.apache.catalina.valves.ValveBase基类。 以RequestDumperValve为例,
RequestDumperValve是打印出request及response信息的valve。其实现方法为:
可以很清晰的看出,它打印出了request及response的信息,其中红色部分显示它调用valve链表中的下一个valve。我们可以这样配置它;
这样,只要访问此host下的所有context,都会打印出调试信息。 Valve的应用有很多,例如cluster,SSO等,会有专门一章来讲讲。
源码面前,了无秘密
----侯捷
在tomcat架构分析(valve机制)(http://gearever.iteye.com/blog/1536022)里已经对valve的机制做了分析。现在通过源码来加深下理解。侯捷说过,源码面前,了无秘密。通过这些代码,可以看到在tomcat中我们经常碰到的一些现象或配置是怎么实现的。
StandardEngineValve
看一下StandardEngineValve的调用逻辑;
public final void invoke(Request request, Response response) throws IOException, ServletException { // 定位host Host host = request.getHost(); if (host == null) { ...... return; } // 调用host的第一个valve host.getPipeline().getFirst().invoke(request, response); }
可以清晰的看到,根据request定位到可以处理的host对象,同时,开始从头调用host里的pipeline上的valve。
StandardHostValve
看一下StandardHostValve的调用逻辑;
public final void invoke(Request request, Response response) throws IOException, ServletException { // 定位context Context context = request.getContext(); if (context == null) { ...... return; } ...... // 调用context的第一个valve context.getPipeline().getFirst().invoke(request, response); // 更新session if (Globals.STRICT_SERVLET_COMPLIANCE) { request.getSession(false); } // Error page processing response.setSuspended(false); //如果有抛异常或某个HTTP错误,导向响应的配置页面 Throwable t = (Throwable) request.getAttribute(Globals.EXCEPTION_ATTR); if (t != null) { throwable(request, response, t); } else { status(request, response); } // Restore the context classloader Thread.currentThread().setContextClassLoader (StandardHostValve.class.getClassLoader()); }
可以清晰的看到,注释部分里根据request定位到可以处理的context对象,同时,开始从头调用context里的pipeline上的valve。在调用完context的所有的valve之后(当然也是context调用完其对应的wrapper上的所有valve之后),蓝色部分显示了拿到response对象时可以做的处理。
熟悉tomcat的可能有配置错误信息的经验,例如;
<error-page> <error-code>404</error-code> <location>/error.jsp</location> </error-page>
它就是为了在用户访问资源出现HTTP 404错误时,将访问重定向到一个统一的错误页面。这样做一是为了美观,另一个主要作用是不会将一些具体的错误信息例如java抛异常时的栈信息暴露给用户,主要还是出于安全的考虑。 上述代码中的注释部分就是实现这个重定向功能。
StandardContextValve
看一下StandardContextValve的调用逻辑;其代码比较多,只贴一些比较核心的吧。
public final void invoke(Request request, Response response) throws IOException, ServletException { ...... // 定位wrapper Wrapper wrapper = request.getWrapper(); if (wrapper == null) { notFound(response); return; } else if (wrapper.isUnavailable()) { ...... } // Normal request processing //web.xml中配置web-app/listener/listener-class Object instances[] = context.getApplicationEventListeners(); ServletRequestEvent event = null; //响应request初始化事件,具体的响应listener是可配置的 ...... //调用wrapper的第一个valve wrapper.getPipeline().getFirst().invoke(request, response); //响应request撤销事件,具体的响应listener是可配置的 ...... }
可以清晰的看到,注释部分里根据request定位到可以处理的wrapper对象,同时,开始从头调用wrapper里的pipeline上的valve。 需要注意的是,这里在调用wrapper的valve前后,分别有响应request初始化及撤销事件的逻辑,tomcat有一整套事件触发体系,这里限于篇幅就不阐述了。有时间专门说。
StandardWrapperValve
看一下StandardWrapperValve的调用逻辑;其代码比较多,只贴一些比较核心的吧;
public final void invoke(Request request, Response response) throws IOException, ServletException { ...... requestCount++; //定位wrapper StandardWrapper wrapper = (StandardWrapper) getContainer(); Servlet servlet = null; Context context = (Context) wrapper.getParent(); ...... // Allocate a servlet instance to process this request try { if (!unavailable) { //加载servlet servlet = wrapper.allocate(); } } catch (UnavailableException e) { ...... } ...... // 根据配置建立一个filter-servlet的处理链表,servlet在链表的尾端 ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance(); ApplicationFilterChain filterChain = factory.createFilterChain(request, wrapper, servlet); // Reset comet flag value after creating the filter chain request.setComet(false); // Call the filter chain for this request // NOTE: This also calls the servlet's service() method try { String jspFile = wrapper.getJspFile(); if (jspFile != null) request.setAttribute(Globals.JSP_FILE_ATTR, jspFile); else request.removeAttribute(Globals.JSP_FILE_ATTR); if ((servlet != null) && (filterChain != null)) { // Swallow output if needed if (context.getSwallowOutput()) { try { SystemLogHandler.startCapture(); if (comet) { filterChain.doFilterEvent(request.getEvent()); request.setComet(true); } else { //调用filter-servlet链表 filterChain.doFilter(request.getRequest(), response.getResponse()); } } finally { String log = SystemLogHandler.stopCapture(); if (log != null && log.length() > 0) { context.getLogger().info(log); } } } else { if (comet) { request.setComet(true); filterChain.doFilterEvent(request.getEvent()); } else { //调用filter-servlet链表 filterChain.doFilter (request.getRequest(), response.getResponse()); } } } request.removeAttribute(Globals.JSP_FILE_ATTR); } catch (ClientAbortException e) { request.removeAttribute(Globals.JSP_FILE_ATTR); throwable = e; exception(request, response, e); } ...... }
可以清晰的看到,注释部分里,先是能拿到相应的wrapper对象;然后完成加载wrapper对象中的servlet,例如如果是jsp,将完成jsp编译,然后加载servlet等;再然后,根据配置生成一个filter栈,通过执行栈,调用完所有的filter之后,就调用servlet,如果没有配置filter,就直接调用servlet,生成filter栈是通过request的URL模式匹配及servlet名称来实现的,具体涉及的东西在tomcat的servlet规范实现中再阐述吧。
以上,完成了一整套servlet调用的过程。通过上面的阐述,可以看见valve是个很灵活的机制,通过它可以实现很大的扩展。
Valve的应用及定制化
Tomcat除了提供上面提到的几个标准的valve实现外,也提供了一些用于调试程序的valve的实现。实现valve需要继承org.apache.catalina.valves.ValveBase基类。 以RequestDumperValve为例,
引用
org.apache.catalina.valves.RequestDumperValve
RequestDumperValve是打印出request及response信息的valve。其实现方法为:
public void invoke(Request request, Response response) throws IOException, ServletException { Log log = container.getLogger(); // Log pre-service information log.info("REQUEST URI =" + request.getRequestURI()); ...... log.info(" queryString=" + request.getQueryString()); ...... log.info("-------------------------------------------------------"); // 调用下一个valve getNext().invoke(request, response); // Log post-service information log.info("-------------------------------------------------------"); ...... log.info(" contentType=" + response.getContentType()); Cookie rcookies[] = response.getCookies(); for (int i = 0; i < rcookies.length; i++) { log.info(" cookie=" + rcookies[i].getName() + "=" + rcookies[i].getValue() + "; domain=" + rcookies[i].getDomain() + "; path=" + rcookies[i].getPath()); } String rhnames[] = response.getHeaderNames(); for (int i = 0; i < rhnames.length; i++) { String rhvalues[] = response.getHeaderValues(rhnames[i]); for (int j = 0; j < rhvalues.length; j++) log.info(" header=" + rhnames[i] + "=" + rhvalues[j]); } log.info(" message=" + response.getMessage()); log.info("========================================================"); }
可以很清晰的看出,它打印出了request及response的信息,其中红色部分显示它调用valve链表中的下一个valve。我们可以这样配置它;
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"> <Valve className="org.apache.catalina.valves.RequestDumperValve"/> <Context path="/my" docBase=" /usr/local/tomcat/backup/my" > </Context> <Context path="/my2" docBase=" /usr/local/tomcat/backup/my" > </Context> </Host>
这样,只要访问此host下的所有context,都会打印出调试信息。 Valve的应用有很多,例如cluster,SSO等,会有专门一章来讲讲。
评论
2 楼
tmj_159
2013-01-21
不错,俺准备今天全部看完
1 楼
飞天奔月
2012-05-24
楼主对tomcat 研究很深刻
我接触的主要是tomcat rss关注学习楼主的帖子
我接触的主要是tomcat rss关注学习楼主的帖子
发表评论
-
mina架构分析 (NIO 网络接口)
2013-04-10 23:39 6214出处:http://gearever.iteye.com A ... -
tomcat架构分析 (connector NIO 实现)
2013-04-09 00:43 27005出处:http://gearever.iteye.com 上 ... -
tomcat架构分析(connector BIO 实现)
2013-04-03 17:41 12610出处:http://gearever.iteye. ... -
tomcat架构分析 (JNDI体系绑定)
2012-06-13 16:42 8558出处:http://gearever.iteye. ... -
tomcat架构分析 (JNDI配置)
2012-06-07 11:46 7698出处:http://gearever.iteye.com J ... -
tomcat架构分析 (Session管理)
2012-06-01 12:34 20487出处:http://gearever.iteye.com S ... -
tomcat架构分析-索引
2012-05-30 21:26 7310出处:http://gearever.iteye.com ... -
tomcat 性能之connector
2012-05-30 20:55 2655今天重新分析了一下tomcat的connector接口的阻塞模 ... -
tomcat架构分析(valve机制)
2012-05-21 10:00 16666出处:http://gearever.iteye. ... -
tomcat架构分析(容器类)
2012-05-17 14:32 14869出处:http://gearever.itey ... -
tomcat架构分析(概览)
2012-05-16 16:23 16305出处:http://gearever.iteye.com T ... -
重新开始
2012-05-16 16:04 143之前架了个blog在GAE上,但是不是很稳定,GAE时常被盾, ...
相关推荐
介绍了tomcat的架构,从源码分析tomcat组成!
以类图,剪短的文字讲解了tomcat的架构。真正做到会用tomcat和懂tomcat内部运行机制。
Tomcat源码剖析 : 整体架构 层层分析 源码解析 架构分析 (Http服务器功能:Socket通信(TCP/IP)、解析Http报文 Servlet容器功能:有很多Servlet(自带系统级Servlet+自定义Servlet),Servlet处理具体的业务逻辑...
Tomcat架构解析文档.zip
tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载
Tomcat系统架构分析 深入学习tomcat 了解tomcat架构
本书只是从架构设计上,对Tomcat的各组件进行了概念性讲解,如果你想阅读Tomcat的源码,本书的内容会让你更容易了解Tomcat的组件结构、设计方案,更容易去由概要到具体的熟悉Tomcat各组件的实现。 其次,本书不局限...
Spring源码分析,web源码分析,Tomcat架构源码分析都是非常深入的源码级课程,期待研究设计模式和深入学习源码内功的朋友们,一定要仔细的学习研究。 (0);目录中文件数:1个 ├─3.代码.zip (1)\1.笔记;目录中文...
tomcat9.0源码
?通过剖析TOMCAT启动及请求流程来了解TOMCAT核心组件及动作原理 ...通过剖析核心组件的源码来深入理解TOMCAT内部原理?介绍实际项目中开发的TOMCAT插件,附源码?了解uml图绘制方法及工具介绍,并介绍常见开源框架的uml图
tomcat 源码分析系列文档 http深入分析,tomcat中类的加载,tomcat的启动,tomcat的容器思想,
简易模拟tomcat服务器项目源码java学习CS架构网络编程;简易模拟tomcat服务器项目源码java学习CS架构网络编程;简易模拟tomcat服务器项目源码java学习CS架构网络编程;简易模拟tomcat服务器项目源码java学习CS架构...
这些资源文档是本人在网上搜索了好多关于tomcat源码讲解的文章之后,觉得对tomcat6源码讲解不错的文章的整理,文档有别人分析,本人只是整理;
Tomcat源码Tomcat源码Tomcat源码Tomcat源码Tomcat源码Tomcat源码Tomcat源码
tomcat的源码解析资料,加上tomcat的pdf解析中文版的,tomcat的源码。 挺不错的资源,大家可以学习下。
tomcat 架构解析和优化。pdf tomcat 架构解析和优化。pdftomcat 架构解析和优化。pdf
tomcat架构原理剖析,tomcat架构原理剖析,tomcat架构原理剖析。
tomcat架构解析_PDF电子书下载 高清 带索引书签目录_刘光瑞(著) 人民邮电出版社
tomcat的基础脚本分析 tomcat的源码启动分析 tomcat的web应用启动分析 tomcat的socket分析 tomcat的cocket与容器对接时序分析
tomcat6,7源码