How Tomcat Works(五)

系统 2240 0

本文接下来介绍tomcat的默认连接器,Tomcat中的默认连接器必须满足以下要求:

  • 实现org.apache.catalina.Connector接口

  • 负责创建实现org.apache.catalina.Request接口的Request对象

  • 负责创建实现org.apache.catalina.Response接口的Response对象

org.apache.catalina.Connector接口最重要的方法是getContainer() 、setContainer()、creatRequest()、 creatResponse(),setContainer()方法用于设置相关联的servlet容器,getContainer()方法获取相关连的servlet容器,creatRequest()方法为http请求创建request对象,creatResponse()方法创建response对象

下面来分析HttpConnector类实现,HttpConnector类同时实现了org.apache.catalina.Connector接口org.apache.catalina.Lifecycle接口(用于生命周期管理)、java.lang.Runnable接口(多线程接口)

在HttpConnector对象的初始化方法initialize()里面,调用私有方法open(),创建ServerSocket实例

      
        private
      
      
         ServerSocket open()
    
      
      
        throws
      
      
         IOException, KeyStoreException, NoSuchAlgorithmException,
           CertificateException, UnrecoverableKeyException,
           KeyManagementException
    {

        
      
      
        //
      
      
         Acquire the server socket factory for this Connector
      
      
        ServerSocketFactory factory =
      
         getFactory();

        
      
      
        //
      
      
         If no address is specified, open a connection on all addresses
      
      
        if
      
       (address == 
      
        null
      
      
        ) {
            log(sm.getString(
      
      "httpConnector.allAddresses"
      
        ));
            
      
      
        try
      
      
         {
                
      
      
        return
      
      
         (factory.createSocket(port, acceptCount));
            } 
      
      
        catch
      
      
         (BindException be) {
                
      
      
        throw
      
      
        new
      
       BindException(be.getMessage() + ":" +
      
         port);
            }
        }

        
      
      
        //
      
      
         Open a server socket on the specified address
      
      
        try
      
      
         {
            InetAddress is 
      
      =
      
         InetAddress.getByName(address);
            log(sm.getString(
      
      "httpConnector.anAddress"
      
        , address));
            
      
      
        try
      
      
         {
                
      
      
        return
      
      
         (factory.createSocket(port, acceptCount, is));
            } 
      
      
        catch
      
      
         (BindException be) {
                
      
      
        throw
      
      
        new
      
       BindException(be.getMessage() + ":" + address +
                                        ":" +
      
         port);
            }
        } 
      
      
        catch
      
      
         (Exception e) {
            log(sm.getString(
      
      "httpConnector.noAddress"
      
        , address));
            
      
      
        try
      
      
         {
                
      
      
        return
      
      
         (factory.createSocket(port, acceptCount));
            } 
      
      
        catch
      
      
         (BindException be) {
                
      
      
        throw
      
      
        new
      
       BindException(be.getMessage() + ":" +
      
         port);
            }
        }

    }
      
    

上面的ServerSocketFactory factory = getFactory()显然是创建ServerSocket实例的工厂,方法如下

      
        /**
      
      
        
     * Return the server socket factory used by this Container.
     
      
      
        */
      
      
        public
      
      
         ServerSocketFactory getFactory() {

        
      
      
        if
      
       (
      
        this
      
      .factory == 
      
        null
      
      
        ) {
            
      
      
        synchronized
      
       (
      
        this
      
      
        ) {
                
      
      
        this
      
      .factory = 
      
        new
      
      
         DefaultServerSocketFactory();
            }
        }
        
      
      
        return
      
       (
      
        this
      
      
        .factory);

    }
      
    

工厂类DefaultServerSocketFactory实现了ServerSocketFactory接口

      
        public
      
      
        final
      
      
        class
      
       DefaultServerSocketFactory 
      
        implements
      
      
         ServerSocketFactory {
   
      
      
        public
      
       ServerSocket createSocket (
      
        int
      
      
         port)
    
      
      
        throws
      
      
         IOException, KeyStoreException, NoSuchAlgorithmException,
           CertificateException, UnrecoverableKeyException,
           KeyManagementException {

        
      
      
        return
      
       (
      
        new
      
      
         ServerSocket(port));

    }
   
      
      
        public
      
       ServerSocket createSocket (
      
        int
      
       port, 
      
        int
      
      
         backlog)
    
      
      
        throws
      
      
         IOException, KeyStoreException, NoSuchAlgorithmException,
           CertificateException, UnrecoverableKeyException,
           KeyManagementException {

        
      
      
        return
      
       (
      
        new
      
      
         ServerSocket(port, backlog));

    }
    
      
      
        public
      
       ServerSocket createSocket (
      
        int
      
       port, 
      
        int
      
      
         backlog,
                                      InetAddress ifAddress)
    
      
      
        throws
      
      
         IOException, KeyStoreException, NoSuchAlgorithmException,
           CertificateException, UnrecoverableKeyException,
           KeyManagementException {

        
      
      
        return
      
       (
      
        new
      
      
         ServerSocket(port, backlog, ifAddress));

    }

}
      
    

下面接着分析用于生命周期的start()方法

      
        /**
      
      
        
     * Begin processing requests via this Connector.
     *
     * 
      
      
        @exception
      
      
         LifecycleException if a fatal startup error occurs
     
      
      
        */
      
      
        public
      
      
        void
      
       start() 
      
        throws
      
      
         LifecycleException {

        
      
      
        //
      
      
         Validate and update our current state
      
      
        if
      
      
         (started)
            
      
      
        throw
      
      
        new
      
      
         LifecycleException
                (sm.getString(
      
      "httpConnector.alreadyStarted"
      
        ));
        threadName 
      
      = "HttpConnector[" + port + "]"
      
        ;
        lifecycle.fireLifecycleEvent(START_EVENT, 
      
      
        null
      
      
        );
        started 
      
      = 
      
        true
      
      
        ;

        
      
      
        //
      
      
         Start our background thread
      
      
                threadStart();

        
      
      
        //
      
      
         Create the specified minimum number of processors
      
      
        while
      
       (curProcessors <
      
         minProcessors) {
            
      
      
        if
      
       ((maxProcessors > 0) && (curProcessors >=
      
         maxProcessors))
                
      
      
        break
      
      
        ;
            HttpProcessor processor 
      
      =
      
         newProcessor();
            recycle(processor);
        }

    }
      
    

首先是启动HttpConnector连接器线程,然后是初始化最少数量的HttpProcessor处理器入栈

      
        /**
      
      
        
     * Start the background processing thread.
     
      
      
        */
      
      
        private
      
      
        void
      
      
         threadStart() {

        log(sm.getString(
      
      "httpConnector.starting"
      
        ));

        thread 
      
      = 
      
        new
      
       Thread(
      
        this
      
      
        , threadName);
        thread.setDaemon(
      
      
        true
      
      
        );
        thread.start();

    }
      
    

由于HttpConnector连接器实现了java.lang.Runnable接口,我们分析它的run()方法实现

      
        /**
      
      
        
     * 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
      
       (!
      
        stopped) {
            
      
      
        //
      
      
         Accept the next incoming connection from the server socket
      
      
            Socket socket = 
      
        null
      
      
        ;
            
      
      
        try
      
      
         {
                
      
      
        //
      
      
                        if (debug >= 3)
                
      
      
        //
      
      
                            log("run: Waiting on serverSocket.accept()");
      
      
                socket =
      
         serverSocket.accept();
                
      
      
        //
      
      
                        if (debug >= 3)
                
      
      
        //
      
      
                            log("run: Returned from serverSocket.accept()");
      
      
        if
      
       (connectionTimeout > 0
      
        )
                    socket.setSoTimeout(connectionTimeout);
                socket.setTcpNoDelay(tcpNoDelay);
            } 
      
      
        catch
      
      
         (AccessControlException ace) {
                log(
      
      "socket accept security exception"
      
        , ace);
                
      
      
        continue
      
      
        ;
            } 
      
      
        catch
      
      
         (IOException e) {
                
      
      
        //
      
      
                        if (debug >= 3)
                
      
      
        //
      
      
                            log("run: Accept returned IOException", e);
      
      
        try
      
      
         {
                    
      
      
        //
      
      
         If reopening fails, exit
      
      
        synchronized
      
      
         (threadSync) {
                        
      
      
        if
      
       (started && !
      
        stopped)
                            log(
      
      "accept error: "
      
        , e);
                        
      
      
        if
      
       (!
      
        stopped) {
                            
      
      
        //
      
      
                            if (debug >= 3)
                            
      
      
        //
      
      
                                log("run: Closing server socket");
      
      
                                    serverSocket.close();
                            
      
      
        //
      
      
                                if (debug >= 3)
                            
      
      
        //
      
      
                                    log("run: Reopening server socket");
      
      
                            serverSocket =
      
         open();
                        }
                    }
                    
      
      
        //
      
      
                            if (debug >= 3)
                    
      
      
        //
      
      
                                log("run: IOException processing completed");
      
      
                } 
      
        catch
      
      
         (IOException ioe) {
                    log(
      
      "socket reopen, io problem: "
      
        , ioe);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (KeyStoreException kse) {
                    log(
      
      "socket reopen, keystore problem: "
      
        , kse);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (NoSuchAlgorithmException nsae) {
                    log(
      
      "socket reopen, keystore algorithm problem: "
      
        , nsae);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (CertificateException ce) {
                    log(
      
      "socket reopen, certificate problem: "
      
        , ce);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (UnrecoverableKeyException uke) {
                    log(
      
      "socket reopen, unrecoverable key: "
      
        , uke);
                    
      
      
        break
      
      
        ;
                } 
      
      
        catch
      
      
         (KeyManagementException kme) {
                    log(
      
      "socket reopen, key management problem: "
      
        , kme);
                    
      
      
        break
      
      
        ;
                }

                
      
      
        continue
      
      
        ;
            }

            
      
      
        //
      
      
         Hand this socket off to an appropriate processor
      
      
            HttpProcessor processor =
      
         createProcessor();
            
      
      
        if
      
       (processor == 
      
        null
      
      
        ) {
                
      
      
        try
      
      
         {
                    log(sm.getString(
      
      "httpConnector.noProcessor"
      
        ));
                    socket.close();
                } 
      
      
        catch
      
      
         (IOException e) {
                    ;
                }
                
      
      
        continue
      
      
        ;
            }
            
      
      
        //
      
      
                    if (debug >= 3)
            
      
      
        //
      
      
                        log("run: Assigning socket to processor " + processor);
      
      
                    processor.assign(socket);

            
      
      
        //
      
      
         The processor will recycle itself when it finishes
      
      
        
        }

        
      
      
        //
      
      
         Notify the threadStop() method that we have shut ourselves down
        
      
      
        //
      
      
                if (debug >= 3)
        
      
      
        //
      
      
                    log("run: Notifying threadStop() that we have shut down");
      
      
        synchronized
      
      
         (threadSync) {
            threadSync.notifyAll();
        }

    }
      
    

上面方法中,监听客户端的http请求,当监听到http请求时,获取Socket实例,然后委派给HttpProcessor对象进行处理(处理器线程吧),最后是如果收到停止连接器线程命令, 则事件通知可以停止线程了

在上面我们还没有来得及分析HttpProcessor对象的初始化相关,所以要重新回到start()方法(源码分析有时要跟踪方法中对多个其他方法的调用,深度优先则顾此失彼,难以兼顾;而广度优先则不便纵向深入)

      
        //
      
      
         Create the specified minimum number of processors
      
      
        while
      
       (curProcessors <
      
         minProcessors) {
            
      
      
        if
      
       ((maxProcessors > 0) && (curProcessors >=
      
         maxProcessors))
                
      
      
        break
      
      
        ;
            HttpProcessor processor 
      
      =
      
         newProcessor();
            recycle(processor);
        }
      
    

这里是创建最少数量的HttpProcessor处理器并入栈,我们先分析newProcessor()方法的实现

      
        /**
      
      
        
     * Create and return a new processor suitable for processing HTTP
     * requests and returning the corresponding responses.
     
      
      
        */
      
      
        private
      
      
         HttpProcessor newProcessor() {

        
      
      
        //
      
      
                if (debug >= 2)
        
      
      
        //
      
      
                    log("newProcessor: Creating new processor");
      
      
        HttpProcessor processor = 
      
        new
      
       HttpProcessor(
      
        this
      
      , curProcessors++
      
        );
        
      
      
        if
      
       (processor 
      
        instanceof
      
      
         Lifecycle) {
            
      
      
        try
      
      
         {
                ((Lifecycle) processor).start();
            } 
      
      
        catch
      
      
         (LifecycleException e) {
                log(
      
      "newProcessor"
      
        , e);
                
      
      
        return
      
       (
      
        null
      
      
        );
            }
        }
        created.addElement(processor);
        
      
      
        return
      
      
         (processor);

    }
      
    

我们可以看到,这里主要是实例化HttpProcessor对象,传入HttpConnector实例本身(里面要用到HttpConnector对象的创建Request对象方法和创建Response对象方法),然后向上转型为Lifecycle接口类型,并调用它的start()方法,接着Vector created = new Vector()成员变量添加该HttpProcessor对象(Vector实现List接口,内部采用数组实现,其操作方法支持线程同步),最后返回实例

      
        /**
      
      
        
     * Recycle the specified Processor so that it can be used again.
     *
     * 
      
      
        @param
      
      
         processor The processor to be recycled
     
      
      
        */
      
      
        void
      
      
         recycle(HttpProcessor processor) {

        
      
      
        //
      
      
                if (debug >= 2)
        
      
      
        //
      
      
                    log("recycle: Recycling processor " + processor);
      
      
                processors.push(processor);

    }
      
    

这里将HttpProcessor对象入栈,成员变量Stack processors = new Stack()继承自 Vector ,是一种先进后出的数据结构

我们现在来分析run()方法里面的相关源码,也许更容易理解

      
        /**
      
      
        
     * Create (or allocate) and return an available processor for use in
     * processing a specific HTTP request, if possible.  If the maximum
     * allowed processors have already been created and are in use, return
     * <code>null</code> instead.
     
      
      
        */
      
      
        private
      
      
         HttpProcessor createProcessor() {

        
      
      
        synchronized
      
      
         (processors) {
            
      
      
        if
      
       (processors.size() > 0
      
        ) {
                
      
      
        //
      
      
         if (debug >= 2)
                
      
      
        //
      
      
         log("createProcessor: Reusing existing processor");
      
      
        return
      
      
         ((HttpProcessor) processors.pop());
            }
            
      
      
        if
      
       ((maxProcessors > 0) && (curProcessors <
      
         maxProcessors)) {
                
      
      
        //
      
      
         if (debug >= 2)
                
      
      
        //
      
      
         log("createProcessor: Creating new processor");
      
      
        return
      
      
         (newProcessor());
            } 
      
      
        else
      
      
         {
                
      
      
        if
      
       (maxProcessors < 0
      
        ) {
                    
      
      
        //
      
      
         if (debug >= 2)
                    
      
      
        //
      
      
         log("createProcessor: Creating new processor");
      
      
        return
      
      
         (newProcessor());
                } 
      
      
        else
      
      
         {
                    
      
      
        //
      
      
         if (debug >= 2)
                    
      
      
        //
      
      
         log("createProcessor: Cannot create new processor");
      
      
        return
      
       (
      
        null
      
      
        );
                }
            }
        }

    }
      
    

这里是从Stack processors = new Stack()成员变量里面获取HttpProcessor对象 ,后面的代码不用多加解释了吧,你懂的!

后面那段代码是干嘛的

      
        //
      
      
         Notify the threadStop() method that we have shut ourselves down
        
      
      
        //
      
      
                if (debug >= 3)
        
      
      
        //
      
      
                    log("run: Notifying threadStop() that we have shut down");
      
      
        synchronized
      
      
         (threadSync) {
            threadSync.notifyAll();
        }
      
    

我们看到threadStop()方法里面的代码,可以看出上面的代码块是用来通知线程停止的

      
        /**
      
      
        
     * Stop the background processing thread.
     
      
      
        */
      
      
        private
      
      
        void
      
      
         threadStop() {

        log(sm.getString(
      
      "httpConnector.stopping"
      
        ));

        stopped 
      
      = 
      
        true
      
      
        ;
        
      
      
        try
      
      
         {
            threadSync.wait(
      
      5000
      
        );
        } 
      
      
        catch
      
      
         (InterruptedException e) {
            ;
        }
        thread 
      
      = 
      
        null
      
      
        ;

    }
      
    

由于HttpProcessor处理器类的源码分析相对独立,加上篇幅还比较多,因此本文先到这里,下文继续……

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

本系列How Tomcat Works系本人原创 

转载请注明出处 博客园 刺猬的温驯 

本人邮箱: chenying998179 # 163.com ( #改为@

本文链接 http://www.cnblogs.com/chenying99/p/3235530.html

How Tomcat Works(五)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论