`
wu_quanyin
  • 浏览: 208134 次
  • 性别: Icon_minigender_1
  • 来自: 福建省
社区版块
存档分类
最新评论

Tomcat源码---请求处理(接收,线程分配)一

阅读更多

一,在以上文章中tomcat启动已经完毕,接着要做的是消息的请求与响应

以下是tomcat文档中的详解

-----------------------------------------------------------------------------------------------

 

d) Tomcat receives a request on an HTTP port

   d1) The request is received by a separate thread which is waiting in the PoolTcpEndPoint 

        class. It is waiting for a request in a regular ServerSocket.accept() method.

        When a request is received, this thread wakes up.

   d2) The PoolTcpEndPoint assigns the a TcpConnection to handle the request. 

       It also supplies a JMX object name to the catalina container (not used I believe)

   d3) The processor to handle the request in this case is Coyote Http11Processor, 

       and the process method is invoked.

       This same processor is also continuing to check the input stream of the socket

       until the keep alive point is reached or the connection is disconnected.

   d4) The HTTP request is parsed using an internal buffer class (Coyote Http11 Internal Buffer)

       The buffer class parses the request line, the headers, etc and store the result in a 

       Coyote request (not an HTTP request) This request contains all the HTTP info, such

       as servername, port, scheme, etc.

   d5) The processor contains a reference to an Adapter, in this case it is the 

       Coyote Tomcat 5 Adapter. Once the request has been parsed, the Http11 processor

       invokes service() on the adapter. In the service method, the Request contains a 

       CoyoteRequest and CoyoteRespons (null for the first time)

       The CoyoteRequest(Response) implements HttpRequest(Response) and HttpServletRequest(Response)

       The adapter parses and associates everything with the request, cookies, the context through a 

       Mapper, etc

   d6) When the parsing is finished, the CoyoteAdapter invokes its container (StandardEngine)

       and invokes the invoke(request,response) method.

       This initiates the HTTP request into the Catalina container starting at the engine level

   d7) The StandardEngine.invoke() simply invokes the container pipeline.invoke()

   d8) By default the engine only has one valve the StandardEngineValve, this valve simply

       invokes the invoke() method on the Host pipeline (StandardHost.getPipeLine())

   d9) the StandardHost has two valves by default, the StandardHostValve and the ErrorReportValve

   d10) The standard host valve associates the correct class loader with the current thread

        It also retrives the Manager and the session associated with the request (if there is one)

        If there is a session access() is called to keep the session alive

   d11) After that the StandardHostValve invokes the pipeline on the context associated

        with the request.

   d12) The first valve that gets invoked by the Context pipeline is the FormAuthenticator

        valve. Then the StandardContextValve gets invoke.

        The StandardContextValve invokes any context listeners associated with the context.

        Next it invokes the pipeline on the Wrapper component (StandardWrapperValve)

   d13) During the invokation of the StandardWrapperValve, the JSP wrapper (Jasper) gets invoked

        This results in the actual compilation of the JSP.

        And then invokes the actual servlet.

e) Invokation of the servlet class


 

-----------------------------------------------------------------------------------------------

 

消息接收是从org.apache.tomcat.util.net.JIoEndpoint$Acceptor#run 这是tomcat接收请求的开始

 

 /**
         * The background thread that listens for incoming TCP/IP connections and
         * hands them off to an appropriate processor.
         */
        public void run() {

            // Loop until we receive a shutdown command
            while (running) {

                // Loop if endpoint is paused
                while (paused) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }

                // Accept the next incoming connection from the server socket
                try {
              //serversocket执行accept()同意请求
                    Socket socket = serverSocketFactory.acceptSocket(serverSocket);
                    serverSocketFactory.initSocket(socket);
                    // Hand this socket off to an appropriate processor
                    //对scoket进行处理
                    if (!processSocket(socket)) {
                        // Close socket right away
                        try {//响应完毕,关闭socket
                            socket.close();
                        } catch (IOException e) {
                            // Ignore
                        }
                    }
                }catch ( IOException x ) {
                    if ( running ) log.error(sm.getString("endpoint.accept.fail"), x);
                } catch (Throwable t) {
                    log.error(sm.getString("endpoint.accept.fail"), t);
                }

                // The processor will recycle itself when it finishes

            }

        }

    }

 JIoEndpoint#processSocket(socket)

 

 

 /**
     * Process given socket.
     */
    protected boolean processSocket(Socket socket) {
        try {
           //没有线程池时使用默认提供的,以下对这一步进行详解
            if (executor == null) {
                getWorkerThread().assign(socket);
            } else {
                executor.execute(new SocketProcessor(socket));
            }
        } catch (Throwable 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;
    }

 

  getWorkerThread().assign(socket);

 分为两步,getWorkerThread()获取到JIoEndpoint$Worker#run(),这一步在线程池中获取到一个线程并启动它

 

 protected Worker createWorkerThread() {

        synchronized (workers) {
            if (workers.size() > 0) {
                curThreadsBusy++;
                return workers.pop();
            }
            if ((maxThreads > 0) && (curThreads < maxThreads)) {
                curThreadsBusy++;
                if (curThreadsBusy == maxThreads) {
                    log.info(sm.getString("endpoint.info.maxThreads",
                            Integer.toString(maxThreads), address,
                            Integer.toString(port)));
                }
               //从线程中取出线程
                return (newWorkerThread());
            } else {
                if (maxThreads < 0) {
                    curThreadsBusy++;
                    return (newWorkerThread());
                } else {
                    return (null);
                }
            }
        }

    }
---------------------------------------------------------------- 
  //启动线程
   protected Worker newWorkerThread() {

        Worker workerThread = new Worker();
        workerThread.start();
        return (workerThread);

    }

 

   getWorkerThread().assign(socket);这一步中为线程分配socket,使用了同步锁机制

 

      //这个是在Acceptor线程中执行的
        synchronized void assign(Socket socket) {

            // Wait for the Processor to get the previous Socket
            while (available) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }

            // Store the newly available Socket and notify our thread
            this.socket = socket;
            available = true;
            notifyAll();

        }

        
  ------------------------------------------------------------
 //这一步是在Worker线程#run中调用的
        private synchronized Socket await() {

            // Wait for the Connector to provide a new Socket
            while (!available) {
                try {
                    wait();
                } catch (InterruptedException e) {
                }
            }

            // Notify the Connector that we have received this Socket
            Socket socket = this.socket;
            available = false;
            notifyAll();//通知释放锁

            return (socket);

        }
//以上两个方法,是两个线程的执行,等待先对socket赋值再执行

 现在到JIoEndpoint$Worker#run

 

        /**
         * The background thread that listens for incoming TCP/IP connections and
         * hands them off to an appropriate processor.
         */
        public void run() {

            // Process requests until we receive a shutdown signal
            while (running) {

                // Wait for the next socket to be assigned
               //以上所说的等待socket的赋值
                Socket socket = await();
                if (socket == null)
                    continue;

                // Process the request from this socket
                //以下的handler.process(socket)才是真正的对socket开始进行处
               //以上所做的只是分配而已,handler是在                 //org.apache.coyote.http11.Http11Protocol(implements ProtocolHandler)#init
                if (!setSocketOptions(socket) || !handler.process(socket)) {
                    // Close socket
                    try {
                        socket.close();
                    } catch (IOException e) {
                    }
                }

                // Finish up this request
                socket = null;
                recycleWorkerThread(this);//进行回收线程

            }

        }
2
0
分享到:
评论

相关推荐

    apache-tomcat-9.0.8-src源码资源

    - `Engine`:负责接收和分配请求给对应的Host。 - `Host`:代表一个域名,可以托管多个Context。 - `Context`:表示一个Web应用,对应一个WAR文件或解压的目录。 - `Pipeline`和`Valve`:请求处理流水线,Valve...

    tomcat-connectors-1.2.48-src

    `mod_jk`负责在HTTPD服务器端接收请求,然后将这些请求转发到Tomcat,而`jk`则在Tomcat端处理这些请求,并返回响应给`mod_jk`,再由`mod_jk`转发给客户端。 2. **版本兼容性** `tomcat-connectors-1.2.48-src`特别...

    Tomcat 6.0 -- 9.0 及其源码

    深入研究Tomcat源码有助于开发者理解Web应用服务器的内部运作机制,提升系统设计和优化能力,同时也有助于自定义扩展和调试,实现更高效、安全的Web服务。 总之,从Tomcat 6.0到9.0,每个版本都带来了技术的进步和...

    tomcat7.0.42源码,eclipse直接使用

    Eclipse是一个广泛使用的Java集成开发环境(IDE),它支持直接导入和管理Tomcat源码。在Eclipse中,开发者可以通过导入“Existing Projects into Workspace”来加载Tomcat源码。然后,可以利用Eclipse的强大功能,如...

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

    源码解析部分则是对Tomcat源码的深度剖析,涵盖了关键类和方法的作用、设计模式的运用以及性能优化技巧。这有助于开发者理解Tomcat内部的工作流程,例如,如何处理HTTP请求的生命周期,以及线程池是如何调度和管理的...

    tomcat源码,servlet-api源码

    《深入理解Tomcat源码与Servlet-API》 Tomcat,作为Apache软件基金会的顶级项目,是Java Servlet和JavaServer Pages(JSP)的开源Web应用服务器,被广泛应用于中小型企业的Web服务部署。7.0.59版本是Tomcat的一个...

    tomcat-7.0.42-src源码爱好者(已编译导入直接可用)

    通过研究Tomcat源码,开发者可以了解到HTTP请求的处理流程、Servlet容器的工作方式、以及如何高效地管理Web应用。此外,了解Tomcat源码还可以帮助开发者借鉴其设计模式和架构,以便在日常开发中构建更稳定、高效的...

    tomcat-connectors-1.2.40-src.zip

    2. 链接管理:`AprSocketAcceptor`(若使用了Apache Portable Runtime,即APR库)或`NioEndpoint`(Java NIO实现)用于监听指定端口,接收新进来的TCP连接,并分配到工作线程进行处理。 3. 处理线程池:NioEndpoint...

    tomcat-7.0.90-src-源码

    深入Tomcat源码,我们可以学习到以下关键知识点: 1. **Web应用部署**:Tomcat如何解析`WEB-INF/web.xml`配置文件,加载Servlet和Filter,以及如何根据`META-INF/context.xml`设置上下文参数。 2. **生命周期管理*...

    tomcat源码

    Tomcat采用基于线程的模型来处理请求,每个请求都会分配一个工作线程来执行。在`server.xml`配置文件中,可以通过`Executor`元素自定义线程池,以优化性能。 5. **JSP编译与执行** Jasper组件将JSP文件编译为Java...

    tomcat8源码

    Apache Tomcat 8.5.23 源码分析 Apache Tomcat 是一个开源的、免费的Web服务器和Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,...因此,对Tomcat源码的学习对于Java Web开发者来说是至关重要的。

    tomcat-7.0.42源码

    《深入剖析Tomcat 7.0.42源码》 Tomcat,作为Apache软件基金会的一个开源项目,是Java Servlet和JavaServer Pages(JSP)技术的流行应用服务器,广泛应用于各类Web应用的部署和开发。7.0.42版本是Tomcat发展中的一...

    apache-tomcat-8.5.68-src

    Tomcat使用多线程模型处理并发请求,源码中可以看到Executor(执行器)和ThreadPool(线程池)的概念,它们有助于提高系统效率和资源利用率。 6. **安全与权限控制**: Tomcat支持多种安全机制,如SSL/TLS加密、 ...

    tomcat-coyote-7.0.34-sources.jar.zip

    例如`org.apache.tomcat.util.threads.TaskQueue`和`org.apache.tomcat.util.threads.TaskThreadLocal`,它们负责任务的分配和线程上下文的维护,确保了高效的并发处理。 5. **Buffers**:`org.apache.tomcat.util....

    HowTomcatWorks-master.zip

    Tomcat使用线程池来处理并发请求,每个请求会被分配到一个空闲的线程进行处理。线程池的大小可以通过配置文件进行调整,以优化性能。 6. **安全配置** 在`server.xml`中,可以配置Realm(认证域)和Role(角色)...

    apache-tomcat-8.0.47-src.zip

    - **线程模型**:了解Tomcat如何处理并发请求,如何使用工作线程池优化性能。 - **安全管理**:通过源码学习如何配置和实现角色、权限以及访问控制。 - **部署和热更新**:Tomcat如何监测`webapps`目录下的变化,并...

    Tomcat源码 学习java很好的东东 apache-tomcat-6.0.26-src

    Service由一个Engine(引擎)、一个或多个Connectors组成,负责接收请求并转发给Engine处理。Engine管理一组Host(主机),每个Host可以托管多个Web应用。Connector负责连接器角色,将网络请求转换为内部请求,如...

    apache-tomcat-6.0.18源码

    6. **线程模型**:Tomcat使用基于工作线程的模型,即每个请求由一个独立的线程处理。` Coyote`中的`ProtocolHandler`负责调度这些线程。 7. **安全与认证**:Tomcat支持多种安全策略,如Basic、Digest、Form和SSL/...

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

    对于每个接收到的请求,Tomcat会从线程池中取出一个空闲线程来处理。线程会读取Socket中的剩余数据,解析请求,执行相应的Servlet或JSP,然后将结果写回Socket,最后关闭Socket连接。在这个过程中,线程池管理着线程...

    apache-tomcat-9.0.60-windows-x64.zip

    5. **多线程处理**:Tomcat利用多线程模型来处理并发请求,确保在高负载下仍能保持良好的性能。 6. **日志和调试**:Tomcat提供了丰富的日志记录功能,帮助开发者调试和监控应用。日志文件通常位于`logs`目录下。 ...

Global site tag (gtag.js) - Google Analytics