`
lengyun3566
  • 浏览: 453717 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
D59180b9-02f1-3380-840c-ea34da46143c
《Spring Secur...
浏览量:384265
社区版块
存档分类
最新评论

Tomcat源码解读系列(三)——Tomcat对HTTP请求处理的整体流程

 
阅读更多

 

声明:源码版本为Tomcat 6.0.35

前面的文章中介绍了Tomcat初始化的过程,本文将会介绍TomcatHTTP请求的处理的整体流程,更细节的。

在上一篇文章中,介绍到JIoEndpoint 中的内部类Acceptor用来接受Socket请求,并调用processSocket方法来进行请求的处理,所以会从本文这个方法开始进行讲解。

 

protected boolean processSocket(Socket socket) {
        try {
            if (executor == null) {
                getWorkerThread().assign(socket);
            } else {
                executor.execute(new SocketProcessor(socket));
            }
        } catch (Throwable t) {
            //……此处略去若干代码
        }
        return true;
    }

 在以上的代码中,首先会判断是否在server.xml配置了进程池,如果配置了的话,将会使用该线程池进行请求的处理,如果没有配置的话将会使用JIoEndpoint中自己实现的线程池WorkerStack来进行请求的处理,我们将会介绍WorkerStack的请求处理方式。

 

protected Worker getWorkerThread() {
        // Allocate a new worker thread
        synchronized (workers) {
            Worker workerThread;
            while ((workerThread = createWorkerThread()) == null) {
                try {
                    workers.wait();
                } catch (InterruptedException e) {
                    // Ignore
                }
            }
            return workerThread;
        }
    }

 在以上的代码中,最终返回了一个Worker的实例,有其来进行请求的处理,在这里,我们再看一下createWorkerThread方法,该方法会生成或者在线程池中取到一个线程。

 

protected Worker createWorkerThread() {
        synchronized (workers) {
            if (workers.size() > 0) {
            //如果线程池中有空闲的线程,取一个
                curThreadsBusy++;
                return workers.pop();
            }
            if ((maxThreads > 0) && (curThreads < maxThreads)) {
                //如果还没有超过最大线程数,会新建一个线程
                curThreadsBusy++;
                return (newWorkerThread());
            } else {
                if (maxThreads < 0) {
                    curThreadsBusy++;
                    return (newWorkerThread());
                } else {
                    return (null);
                }
            }
        }
    }

 到此,线程已经获取了,接下来,最关键的是调用线程实现Workerrun方法:

 

public void run() {
            // Process requests until we receive a shutdown signal
            while (running) {
                // Wait for the next socket to be assigned
                Socket socket = await();
                if (socket == null)
                    continue;
                   if (!setSocketOptions(socket) || !handler.process(socket)) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                    }
                }
                socket = null;
                recycleWorkerThread(this);
            }
        }

 这里跟请求处理密切相关的是handler.process(socket)这一句代码,此处handle对应的类是Http11Protocol中的内部类Http11ConnectionHandler,在此后的处理中,会有一些请求的预处理,我们用一个时序图来表示一下:



 在这个过程中,会对原始的socket进行一些处理,到CoyoteAdapter时,接受的参数已经是org.apache.coyote.Requestorg.apache.coyote.Response了,但是要注意的是,此时这两个类并不是我们常用的HttpServletRequestHttpServletResponse的实现类,而是Tomcat内部的数据结构,存储了和输入、输出相关的信息。值得注意的是,在CoyoteAdapterservice方法中,会调用名为postParseRequest的方法,在这个方法中,会解析请求,调用MapperMap方法来确定该请求该由哪个EngineHostContext来处理。

在以上的信息处理完毕后,在CoyoteAdapterservice方法中,会调用这样一个方法:

 

connector.getContainer().getPipeline().getFirst().invoke(request, response);

 这个方法会涉及到Tomcat组件中的Container实现类的重要组成结构,即每个容器类组件都有一个pipeline属性,这个属性控制请求的处理过程,在pipeline上可以添加Valve,进而可以控制请求的处理流程。可以用下面的图来表示,请求是如何流动的:



 可以将请求想象成水的流动,请求需要在各个组件之间流动,中间经过若干的水管和水阀,等所有的水阀走完,请求也就处理完了,而每个组件都会有一个默认的水阀(以Standard作为类的前缀)来进行请求的处理,如果业务需要的话,可以自定义Valve,将其安装到容器中。

后面的处理过程就比较类似了,会按照解析出来的EngineHostContext的顺序来进行处理。这里用了两张算不上标准的时序图来描述这一过程:




 在以上的流程中,会一层层地调用各个容器组件的Valveinvoke方法,其中StandardWrapperValve这个标准阀门将会调用StandardWrapperallocate方法来获取真正要执行的Servlet(在Tomcat中所有的请求最终都会映射到一个Servlet,静态资源和JSP也是如此),并按照请求的地址来构建过滤器链,按照顺序执行各个过滤器并最终调用目标Servletservice方法,来完成业务的真正处理。

 

 

 

 

 

以上的处理过程中,涉及到很多重要的代码,后续的文章会择期要者进行解析,如:

      Mapper中的internalMapWrapper方法(用来匹配对应的Servlet

       ApplicationFilterFactorycreateFilterChain方法(用来创建该请求的过滤器链)

       ApplicationFilterChaininternalDoFilter方法(用来执行过滤器方法以及最后的Servlet

       Http11Processor中的process方法、prepareRequest方法以及prepareResponse方法(用来处理HTTP请求相关的协议、参数等信息)

至此,我们简单了解一个请求的处理流程。

  • 大小: 96.9 KB
  • 大小: 165.9 KB
  • 大小: 140.3 KB
  • 大小: 159.5 KB
6
0
分享到:
评论
5 楼 lengyun3566 2012-09-13  
1927105 写道
w156445045 写道
请问下博主是用的啥工具画图的啊?图不错,很赞。


同问

呵呵 edraw 叫做亿图图示专家
4 楼 lengyun3566 2012-09-13  
w156445045 写道
请问下博主是用的啥工具画图的啊?图不错,很赞。

呵呵 edraw 叫做亿图图示专家
3 楼 1927105 2012-09-12  
w156445045 写道
请问下博主是用的啥工具画图的啊?图不错,很赞。


同问
2 楼 w156445045 2012-09-10  
请问下博主是用的啥工具画图的啊?图不错,很赞。
1 楼 liuningbo 2012-09-10  
不错!顶起

相关推荐

    tomcat 源码分析系列文档

    1. "Tomcat处理HTTP请求源码分析.doc":详细阐述了Tomcat接收到HTTP请求后,如何解析请求头、执行请求方法、构造响应的过程,包括Servlet生命周期和请求转发等。 2. "Tomcat的类载入器以及源码分析.doc":详细介绍...

    tomcat源码+文档pdf+源码解析

    这有助于开发者理解Tomcat内部的工作流程,例如,如何处理HTTP请求的生命周期,以及线程池是如何调度和管理的。对于那些想要定制Tomcat或者解决特定问题的人来说,源码解析是极其宝贵的资源。 总之,这个资源包对于...

    tomcat源码阅读(一)——环境搭建

    本篇将聚焦于"Tomcat源码阅读(一)——环境搭建",探讨如何搭建一个适合源码学习的开发环境。 首先,我们需要了解Tomcat是什么。Tomcat是一款开源的Java Servlet容器,由Apache软件基金会维护,实现了Java EE中的...

    tomcat 分配请求之——socket获取请求

    标题“Tomcat分配请求之——Socket获取请求”主要涉及的是Tomcat服务器在处理HTTP请求时的核心机制。在Web服务器中,Tomcat是一个广泛使用的开源应用服务器,它负责解析并响应来自客户端(如浏览器)的HTTP请求。这...

    tomcat源码解析

    这个部分介绍了如何构建一个简单的Servlet容器实例,包括处理HTTP请求的基本流程。 - **HttpServer1类**:负责接收HTTP请求并创建Request和Response对象。 - **Request类**:封装HTTP请求的信息。 - **Response类**...

    「Tomcat源码剖析」.pdf

    Tomcat源码剖析 : 整体架构 层层分析 源码解析 架构分析 (Http服务器功能:Socket通信(TCP/IP)、解析Http报文 Servlet容器功能:有很多Servlet(自带系统级Servlet+自定义Servlet),Servlet处理具体的业务逻辑...

    tomcat源码

    处理过程中,请求会经过一系列的过滤器,最后由对应的Servlet处理,完成业务逻辑后,响应结果再通过类似的路径返回给客户端。 4. **线程模型** Tomcat采用基于线程的模型来处理请求,每个请求都会分配一个工作线程...

    02-Tomcat源码解读1

    Tomcat作为一款广泛使用的开源Java Servlet容器,其源码解读对于理解其工作原理至关重要。在深入源码之前,我们需要了解Tomcat的基本架构和关键组件。Tomcat的顶层由Server和Service两个核心组件构成。 **Server...

    tomcat处理一个http请求的详细过程

    tomcat中server配置文件的结构,以及处理一个http请求的全过程

    Ant编译Tomcat源码、MyEclipse导入Tomcat源码、执行Tomcat源码启动Tomcat

    Tomcat的主要组件包括Catalina(核心Servlet容器)、 Coyote(处理HTTP连接)、Jasper(JSP引擎)等。你可以通过阅读源码和官方文档来了解这些组件的工作原理,这对于定制和优化Tomcat性能具有极大价值。 总之,Ant...

    tomcat工作原理深入详解——HowTomcatWorks中文版.pdf

    tomcat工作原理深入详解——HowTomcatWorks中文版.pdf

    Syske#person-learning-note#Tomcat源码分析-壹——启动过程值init方法1

    前言从今天开始,我们开始分析tomcat的源码,至于原因嘛,第一Tomcat是非常优秀的web服务器,它占据着全球一半以上的市场份额,就连spring boot

    Tomcat深入剖析pdf+源码(Tomcat运行原理)

    5. **线程模型**:Tomcat使用线程池处理请求,提高了并发性能。线程池预创建一定数量的线程,以应对突发的高并发请求。 6. **连接器与管道**:Coyote连接器负责接收和发送网络数据,管道(Pipeline)则提供了灵活的...

    tomcat7源码下载

    《深入剖析Tomcat7源码》 ...通过对Tomcat7源码的深入学习,开发者不仅可以了解其工作原理,还能针对具体需求进行定制化开发,提高应用的稳定性和效率。下载并研究Tomcat7源码,对于提升Java Web开发技能大有裨益。

    tomcat6源码分析

    《Tomcat6源码分析——深入理解Web服务器的运行机制》 Tomcat6作为Apache软件基金会的Jakarta项目的一部分,是一款广泛使用的Java Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,为开发和部署...

    tomcat6的源码

    源码中,这些生命周期方法的实现有助于理解Tomcat的内部工作流程。 4. **部署与加载**:Tomcat可以自动或手动部署Web应用程序。源码中的`Host`和`Context`类展示了如何解析WAR文件并加载应用到服务器。 5. **JMX...

    tomcat8源码

    通过研究Tomcat8的源码,我们可以深入理解其内部工作流程,学习如何定制和优化服务器配置,以适应不同的Web应用需求。这不仅有助于提升开发效率,还能帮助我们解决在实际项目中遇到的性能瓶颈和安全问题。因此,对...

    tomcat源码导入myeclipse

    【标题】"Tomcat源码导入MyEclipse"是一个针对Java开发者的重要实践操作,它涉及到两个关键组件:Tomcat服务器和MyEclipse集成开发环境。Tomcat是Apache软件基金会的一个开源项目,它作为Servlet和JavaServer Pages...

    tomcat源码资源包

    这一步骤对于开发者来说极其重要,因为通过查看源码,开发者可以更深入地理解Tomcat处理HTTP请求、管理Servlet、部署Web应用程序以及执行其他核心功能的方式。 Tomcat源码的主要组成部分包括以下几个关键模块: 1....

Global site tag (gtag.js) - Google Analytics