本文主要通过流程图和序列图的方式剖析tomcat请求处理流程。从tomcat6源码分析一和tomcat6源码分析二两篇文章我们对tomcat的总体架构、核心模块、以及tomcat初始化和启动流程有了一个比较详细的了解。多个Connector和一个Container共同组成了一个Service,Service启动后便可以接收和处理用户http/ajp等请求。这里我们依HTTP1.1为例进行分析。Tomcat启动完成后,Acceptor在监听端口监听用户请求。
处理流程
图1 请求处理流程图(1)
图2 请求处理流程图(2)
CoyoteAdapter.service会调用我们的Servlet.service。经过长途跋涉,终于要把请求处理转发到了我们自己的servlet。CoyoteAdapter的处理流程很简单,见下图:
图3 CoyoteAdapter处理流程
Pipeline和Valve
这里要提到两个模块,一个是Pipeline,一个是Valve。Pipeline类似一个管道,Valve是管道中的阀门。每个容器都有一个Pipeline,每个Pipeline可以有多个Valve,但至少有一个ValveBase。每个请求流过管道时,各个Valve会对请求做相应的操作,这类似过滤器功能。
图4 Pipeline接口
图5 Valve接口
图6 Pipeline和Vavle接口
图7 Pipeline和Vavle过滤流程
Connector.getContainer().getPipeline().getFirst().invoke(request,response)请求处理过程如下。Connector.getContainer()得到StandardEngine.getFirst()得到StandardEngineValve。
图8 Valve工作流程
核心处理逻辑在StandardWrapperValve中完成,它包装了我们的Servlet,调用Servlet.service方法处理请求。到这里tomcat把请求转发给我们自己写的Servlet处理。这里为了阐述方便去掉了一些处理细节分析。
StandardWrapperValve.invoke方法的处理逻辑:
- 调用wrapper.allocate()分配一个Servlet
- response.sendAcknowledgement() 发送一个ack到客户端
- request.getRequestPathMB() 获取请求路径
- createFilterChain(request, wrapper, servlet) 创建过滤链
- doFilter 执行过滤链,serlvet.service()方法也在其中
- 回收servlet实例