Tomcat第三篇——一个请求的处理过程

Posted 搬砖小松鼠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Tomcat第三篇——一个请求的处理过程相关的知识,希望对你有一定的参考价值。

目录

一、请求处理流程

Connector中的处理

Container中的处理

二、Connector中对Http协议处理源码解析

BIO的处理

NIO的处理


一、请求处理流程

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简介

JAVA企业应用第三篇TOMCAT配置

深入理解ajax系列第三篇——头部信息

第三篇:白话tornado源码之请求来了

第三篇开始和SpringSecurity的简单交往-处理请求的本质

第三篇开始和SpringSecurity的简单交往-处理请求的本质