Tomcat第三篇——一个请求的处理过程
Posted 搬砖小松鼠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat第三篇——一个请求的处理过程相关的知识,希望对你有一定的参考价值。
目录
一、请求处理流程
Connector中的处理
Tomcat在初始化时会按照xml中配置来初始化不同协议的Connector,Tomcat使用ProtocolHandler来用于扩展不同的协议,包括http协议和ajp协议,在每个协议的内部又依据io类型的不同,分为bio、nio等,组合起来常用的实现类有:Http11Protocol、Http11NioProtocol、AjpProtocol、AjpNioProtocol等。 不同的io内部又是通过不同的EndPoint来处理的,如BIO的JioEndPoint、Nio的NioEndPoint
Connect中的整个请求过程如下图所示:
Container中的处理
在Connector中对请求的协议及参数进行解析后会得到Connector包下的Request和Response对象,经过Adapter的适配,可以得到HttpServletRequest和HttpServletResponse对象,接下来会调用其所在的Service对象下的Container容器的Pipeline进行依次执行
二、Connector中对Http协议处理源码解析
BIO的处理
这里主要以bio的处理为例,主要看的是Http11Protocol中的处理,其对应的EndPoint是JioEndPoint
1.BIO中的启动
(1)初始化一个工作线程池。
注意这个线程池是Connector内部的线程池,最大线程数200
(2)初始化一个栅栏
用来限制链接次数的
(3)启动Acceptor线程
里面的过程就是new了许多Runnable的Acceptor,并开启一个线程跑这个Acceptor,接下来看看Acceptor内部的任务是什么
(4)启动一个守护线程,里面执行超时处理的任务
2.Acceptor中run执行的任务
Acceptor是定义在AbstractEndPoint中的内部抽象类,JioEndPoint等各自进行实现.
(1)判断是否达到最大连接
(2)获取Socket
(3)处理Socket
3.processSocket的处理
代码比较简单,封装成SocketProcessor丢给线程池进行执行(这里的线程池就是前面start中的工作线程池),接下来看看SocketProcessor中是怎么执行的
protected boolean processSocket(Socket socket)
// Process the request from this socket
try
SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);
wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
wrapper.setSecure(isSSLEnabled());
// During shutdown, executor may be null - avoid NPE
if (!running)
return false;
//Wrapper包装一下,封装成一个SocketProcessor并交给线程池执行
getExecutor().execute(new SocketProcessor(wrapper));
catch (RejectedExecutionException x)
log.warn("Socket processing request was rejected for:"+socket,x);
return false;
catch (Throwable t)
ExceptionUtils.handleThrowable(t);
// This means we got an OOM or similar creating a thread, or that
// the pool and its queue are full
log.error(sm.getString("endpoint.process.fail"), t);
return false;
return true;
4.SocketProcessor中的处理
查看其实现的run方法,核心是handler.process方法。那这个Handler又是什么东西呢?
Handler是定义在JioEndPoint中的接口,继承自AbstractEndPoint中定义的Handler接口,他有两个实现分别是ajp和http协议的,上面handler对象就是Http11ConnectionHandler,其process方法在其父类AbstractConnectionHandler中。
在里面会调用Processor的process方法,Processor接口也有很多实现类,这里对应Http11Processor,它的process方法也定义在其父类,AbstractHttp11Processor中,里面会对协议的信息进行解析,并得到org.apache.coyoteo.Request和org.apache.coyoteo.Response对象,接下来对将整个两个对象作为参数,传给Adapter的service方法,Adapter的实现类为CoyoteAdapter
该对象的service方法会将Coyote中的Request和Response转为servlet的Requst对象和Response对象,并调用Service的Contain容器Pipeline的第一个元素进行invoke
NIO的处理
NIO的处理的流程主要是多了一层Poller线程,BIO模式中每个请求都会交给线程池中的一个线程进行处理,线程会阻塞在IO等待上,而NIO则是引入了Selector,当接收到请求时会生成Channel并注册到Selector上,Selector监听到有读写事件时再去调用Handler去处理请求
以上是关于Tomcat第三篇——一个请求的处理过程的主要内容,如果未能解决你的问题,请参考以下文章
JavaWeb入门详解(第三篇)web服务器之Tomcat简介