`
suhuanzheng7784877
  • 浏览: 702645 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
Ff8d036b-05a9-33b5-828a-2633bb68b7e6
读金庸故事,品程序人生
浏览量:47711
社区版块
存档分类
最新评论

Tomcat7.0.28源代码浅读1

阅读更多

 

1.接收Http连接

 

处理连接涉及的主要类是

org.apache.tomcat.util.net.JIoEndpoint的内部类AcceptorJIoEndpoint在启动之初会调用它的startInternal()方法,之后会有单独的线程负责激活Acceptor

    /**
     * 监听TCP/IP连接,并处理他们,分发到HTTP的处理器
     */
    protected class Acceptor extends AbstractEndpoint.Acceptor {

        @Override
        public void run() {

            int errorDelay = 0;
            
            //循环接收tcp-ip连接,直到收到关闭命令
            while (running) {

                // 暂停
                while (paused && running) {
                    state = AcceptorState.PAUSED;
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }
                
                // 停止
                if (!running) {
                    break;
                }
                state = AcceptorState.RUNNING;

                try {
                	
                	//如果当前处理的tcp请求连接的数目已经很多了,等待(默认是200个)
                    countUpOrAwaitConnection();

                    Socket socket = null;
                    try {
                    	
                    	//等待接收下一个tcp请求
                        socket = serverSocketFactory.acceptSocket(serverSocket);
                    } catch (IOException ioe) {
                        countDownConnection();
                        // Introduce delay if necessary
                        errorDelay = handleExceptionWithDelay(errorDelay);
                        // re-throw
                        throw ioe;
                    }
                    // 成功接受了tcp请求
                    errorDelay = 0;

                    // Configure the socket
                    if (running && !paused && setSocketOptions(socket)) {
                    	//用适当的处理器处理Runnable请求
                        if (!processSocket(socket)) {
                        	
                        	//计数器-1,释放正在处理connection的数字
                            countDownConnection();
                            
                            // 关闭tcp连接
                            closeSocket(socket);
                        }
                    } else {
                        countDownConnection();
                        // Close socket right away
                        closeSocket(socket);
                    }
                } catch (IOException x) {
                    if (running) {
                        log.error(sm.getString("endpoint.accept.fail"), x);
                    }
                } catch (NullPointerException npe) {
                    if (running) {
                        log.error(sm.getString("endpoint.accept.fail"), npe);
                    }
                } catch (Throwable t) {
                    ExceptionUtils.handleThrowable(t);
                    log.error(sm.getString("endpoint.accept.fail"), t);
                }
            }
            state = AcceptorState.ENDED;
        }
    }

 

内部类用一个独立的线程运行方式,运行。在没有收到“关闭”状态命令的时候,一直处理接收tcp-ip请求。

 

该类最重要的方法是countUpOrAwaitConnection();processSocket(socket)。前者是控制接收tcp-ip并发连接数的等待机制,后面是处理socket的具体逻辑。

countUpOrAwaitConnection()的方法逻辑如下:

    protected void countUpOrAwaitConnection() throws InterruptedException {
    	
    	//最大连接数是非法数字
        if (maxConnections==-1) return;
        
        //占有锁的钥匙
        LimitLatch latch = connectionLimitLatch;
        
        //获取一个队列中的可用资源,如果当前没有可用的资源,则一直处于等待
        if (latch!=null) latch.countUpOrAwait();
    }

 

其中,LimitLatch是关键的类。该类的内部类Sync又是一个重点。它是AbstractQueuedSynchronizer类的子类,用于同步队列的实现。LimitLatch.countUpOrAwait()方法就是调用了

 

sync.acquireSharedInterruptibly(1);

 

重点就是Sync类以及它的父类AbstractQueuedSynchronizer的解释了

Sync实现,API的解释在注释中

		/**
		 * 在失败时返回负值;如果共享模式下的获取成功但其后续共享模式下的获取不能成功,则返回
		 * 0;如果共享模式下的获取成功并且其后续共享模式下的获取可能够成功
		 * ,则返回正值,在这种情况下,后续等待线程必须检查可用性。在成功的时候,此对象已被获取。
		 */
		@Override
		protected int tryAcquireShared(int ignored) {
			
			//当前新的计数数字
			long newCount = count.incrementAndGet();
			if (!released && newCount > limit) {
				
				// 已经越过最小值
				count.decrementAndGet();
				return -1;
			} else {
				return 1;
			}
		}

 释放计数器,实现如下

		@Override
		protected boolean tryReleaseShared(int arg) {
			
			//原子量减1
			count.decrementAndGet();
			return true;
		}

 

下面我们弱弱的看一看AbstractQueuedSynchronizer.acquireSharedInterruptibly方法的实现

    public final void acquireSharedInterruptibly(int arg) throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();

//尝试调用子类的tryAcquireShared方法,获取失败了走doAcquireSharedInterruptibly逻辑
        if (tryAcquireShared(arg) < 0)
            doAcquireSharedInterruptibly(arg);
    }

 

AbstractQueuedSynchronizer维护了一个双向的队列结构,FIFO共享方式,对外进行信号量的加锁,解锁操作。获取不到>0的信号量,那么请求线程会加入到等待队列中等待,知道别的线程释放了信号量(减1),再次获取后,方可进行下一步的服务。

 

这样,完成了多线程同时发起http请求的同步和阻塞(达到最大http连接数后)机制。

 

留个标记:AbstractQueuedSynchronizer值得深入研究

处理socketJIoEndpoint.processSocket(socket)这句。核心方法体如下

        	//包装一下Socket
            SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);
            
            //HTTP1.1 的最新特性,维护100个http请求,只使用同一个httpconnection
            wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
            // During shutdown, executor may be null - avoid NPE
            if (!running) {
                return false;
            }
            
            //线程池执行一个“处理http socket”的线程
            getExecutor().execute(new SocketProcessor(wrapper));

 

SocketProcessor中就是多次处理Socket请求,到后面还是调用AbstractConnectionHandler类的process方法。

 

关于tomcat接收Http连接的问题。我们看到了,是以上的工作机制。

简单的模块图如下



 

  • 大小: 29.4 KB
分享到:
评论

相关推荐

    apache-tomcat-7.0.28

    Apache Tomcat 7.0.28 是一个广泛使用的开源软件,它是一个实现了Java Servlet、JavaServer Pages(JSP)和Java EE的Web应用程序容器。这个版本是Tomcat服务器的一个特定发行版,专注于稳定性和性能优化。在了解这个...

    Tomcat7.0.28 for windows

    【标题】"Tomcat7.0.28 for windows"涉及的是Apache Tomcat服务器的一个特定版本,即7.0.28,这是针对Windows操作系统优化的。Tomcat是一款开源的、基于Java Servlet和JavaServer Pages (JSP) 技术的Web应用服务器,...

    tomcat7.0.28

    1. 下载并解压apache-tomcat-7.0.28压缩包,这包含了服务器运行所需的所有文件和目录,如`bin`(包含启动和停止脚本)、`conf`(配置文件)、`webapps`(部署Web应用的位置)等。 2. 配置环境变量,如设置CATALINA_...

    Apache Tomcat 最新源代码

    Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache Tomcat 最新源代码Apache ...

    tomcat-7.0.28

    tar zxvf apache-tomcat-7.0.28.tar.gz -C ../software/ cd ../software cp -rp apache-tomcat-7.0.28/ /usr/local/ cd /usr/local/apache-tomcat-7.0.28/ 设置环境变量 vi /etc/profile 加入如下两条 CATALINA_...

    Tomcat8源代码

    **Apache Tomcat 8源代码解析** Apache Tomcat是一款开源的Java Servlet容器,它实现了Java Servlet和JavaServer Pages(JSP)规范,是许多Web应用开发者的重要工具。Tomcat 8是其发展的一个重要版本,引入了许多新...

    tomcat_v7.0.28

    tomcat_v7.0.28各版本绿色版及安装版,包含安装版apache-tomcat-7.0.28.exe,绿色版apache-tomcat-7.0.28.tar.gz、apache-tomcat- 7.0.28.zip、apache-tomcat-7.0.28-windows-i64.zip、apache-tomcat-7.0.28-...

    tomcat6 源代码

    这个源代码压缩包提供了Tomcat6的完整源码,对于开发者来说,深入理解其内部工作原理、优化性能或者定制功能都具有极大的价值。下面将详细介绍Tomcat6的一些关键知识点。 1. **Servlet容器**: Tomcat作为一个...

    apache-tomcat-7.0.28安装版

    apache-tomcat-7.0.28安装版

    tomcat7源代码

    《深入剖析Tomcat7源代码》 Tomcat7是一款广泛使用的开源Java Servlet容器,它实现了Java EE中的Web应用规范,包括Servlet、JSP和EL(Expression Language)等。本资源包含Tomcat7的源代码以及运行所需的jar包,...

    apache-tomcat官网源代码,用于查找servlet源代码

    apache-tomcat官网源代码,用于查找servlet源代码,如果想知道HttpServletRequest等实现代码请下载吧具体源代码位置为:目录名\apache-tomcat-5.5.35-src\servletapi\jsr154\src\share\javax\servlet

    Tomcat6源代码学习(运行源代码及调试)

    1. IDE集成:使用Eclipse或IntelliJ IDEA等IDE,导入Tomcat6源代码项目,设置源代码路径并配置远程调试。 2. 日志配置:修改conf/logging.properties文件,增加日志级别,便于追踪代码执行过程。 3. 使用断点:在IDE...

    可在Eclipse中导入和运行的tomcat源代码

    【标题】:“在Eclipse中导入和运行的Tomcat源代码” 【正文】: Tomcat,作为Apache软件基金会的一个开源项目,是Java Servlet和JavaServer Pages(JSP)的最广泛应用服务器之一。它以其轻量级、高效和易用性而广...

    Tomcat-7.0.28.rar

    Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个Servlet容器,按照Sun Microsystems提供的技术规范,实现了对Servlet和JavaServer Page(JSP)的支持,并提供了作为 Web服务器的一些特有功能,如Tomcat管理...

    Tomcat 8源代码 Servlet源代码

    【标题】"Tomcat 8源代码 Servlet源代码" 涉及到的是Apache Tomcat服务器的源码分析,特别是Servlet容器的相关实现。Tomcat是一个开源的轻量级Web应用服务器,广泛用于部署Java Servlet和JavaServer Pages (JSP)应用...

    Tomcat 7 源代码

    源代码的获取对于开发者来说具有重要意义,因为通过源码,我们可以深入理解Tomcat的工作原理,进行定制化开发,或者优化性能。以下是基于Tomcat 7源代码的一些关键知识点: 1. **Java Servlet**: Java Servlet是...

    Tomcat5.0.28源代码

    《深入剖析Tomcat 5.0.28源代码》 Tomcat,作为Apache软件基金会下的一个开源项目,是Java Servlet和JavaServer Pages(JSP)的容器,它以其轻量级、高效能和易用性赢得了广大开发者的喜爱。Tomcat 5.0.28是其历史...

    Tomcat6.0.41源代码,可直接导入Eclipse

    这个源代码版本提供了深入理解Tomcat工作原理的机会,对于开发者来说是一份宝贵的资源。下面将详细介绍Tomcat 6.0.41源代码中的关键组件、功能以及如何在Eclipse中进行编译和运行。 一、Tomcat架构 Tomcat由几个...

    Tomcat源代码学习研究

    《深入剖析Tomcat源代码:探索底层实现原理》 Tomcat作为开源的Java Servlet容器,是许多Web开发者和系统管理员的首选。它以其轻量级、高效和稳定性著称,而深入理解其源代码,有助于我们更好地优化应用性能,解决...

Global site tag (gtag.js) - Google Analytics