- 请求处理流程分析
- 请求处理流程示意图
- Mapper组件体系结构
- 具体处理流程
- tomcat请求处理最终都经过FilterChain的doFilter方法,FilterChain的实现类是ApplicationFilterChain,所以可以在ApplicationFilterChain的doFilter方法中打断点看执行流程,具体代码执行找如下
service:728, HttpServlet (javax.servlet.http)
internalDoFilter:231, ApplicationFilterChain (org.apache.catalina.core)
doFilter:166, ApplicationFilterChain (org.apache.catalina.core)
invoke:200, StandardWrapperValve (org.apache.catalina.core)
invoke:96, StandardContextValve (org.apache.catalina.core)
invoke:543, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:139, StandardHostValve (org.apache.catalina.core)
invoke:81, ErrorReportValve (org.apache.catalina.valves)
invoke:690, AbstractAccessLogValve (org.apache.catalina.valves)
invoke:87, StandardEngineValve (org.apache.catalina.core)
service:343, CoyoteAdapter (org.apache.catalina.connector)
service:615, Http11Processor (org.apache.coyote.http11)
process:65, AbstractProcessorLight (org.apache.coyote)
process:818, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1616, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1128, ThreadPoolExecutor (java.util.concurrent)
run:628, ThreadPoolExecutor$Worker (java.util.concurrent)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:834, Thread (java.lang)
-
从上面只能看出后半部分流程,前半部分还不知道
-
从之前的tomcat初始化和启动流程文章中可以知道tomcat启动最后一步是AbstractEndpoint.startAcceptorThreads方法,不了解可以点击tomcat初始化和启动流程,AbstractEndpoint是一个抽象类,常用实现类有如下三个,分别对应不同的请求处理方式
- AprEndpoint APR是Apache可移植运行库(Apache portable Run-time libraries)的简称,具体没研究
- NioEndpoint 同步非阻塞
- Nio2Endpoint 异步非阻塞
- AbstractEndpoint.startAcceptorThreads
Acceptor主要监听是否有客户端发来的连接并接收该连接,accept操作是阻塞的。此时返回 SocketChannel对象。Acceptor接收 SocketChannel 对象后要把它设置成非阻塞(后面对客户端连接才去非阻塞模式处理),接着设置套接字属性,封装成非阻塞通道对象。(NioChannel–HTTP、SecureNioChannel–HTTPS),最后将非阻塞通道对象注册到通道队列由 Poller 负责检测事件。
- 上面的startAcceptorThreads方法是在具体实现类NioEndpoint调用startInternal的模板方法
- NioEndpoint.startInternal
- 轮询器----Poller
需要同时对很多连接进行管理,通过不断遍历事件列表,对对应连接的相应事件作出处理。Poller内部依赖 JDK的Selector对象进行轮询,Selector会选择出待处理的事件,每轮询一次就选出若干需要处理的NioChannel,在NIO模式下,每次读取的数据时不确定的,每次读取的数据可能有请求头和请求行,每次只能尝试去解析报文,如果解析不成功则等待下次轮询读取更多数据后再次尝试,如果解析成功则做一些逻辑处理后对客户端响应,这些处理工作在任务定义器中定义。
- Poller中的run方法里面有个核心流程processKey(sk, attachment);
- 由上图可知最终执行的SocketProcessorBase中的run方法,跟上面打断点的代码执行栈正好接上。以上就是tomcat的大概处理流程,里面的很多细节内容太多,涉及到Nio相关的知识,以后再写文章详细讲解