tomcat解析(十六)对客户端请求的处理

来源:互联网 发布:淘宝供销平台怎么填写 编辑:程序博客网 时间:2024/04/26 04:41

前面我们讲到,或者你也可以在server.xml的注释中看到,Connector类是用于接收用户请求并返回处理结果的,整个服务启动及处理过程均在Connector的start方法里,而其实际的内容在于其挂有的ProtocolHandler对象,启动过程会调用其start方法,该方法又会调用到JIoEndpoint的start方法,该方法如下:
  

    实质上是启动了N个线程,线程又是怎么处理的呢,看一下Acceptor类的run方法即可
     

    对于每一个Acceptor线程,均会不断地调用ServerSocket.accept方法来接受客户端的请求,最后调用processSocket方法处理该socket
    

    由于executor为空,因此将执行getWorkerThread().assign(socket);
     

尽管在start方法里已对workers进行了初始化,但这里并不直接返回栈中Worker对象,可看一下WorkerStack类
     

    在JIoEndpoint.start()中,是直接调用该类的构造方法的:
    public WorkerStack(int size) {
        workers = new Worker[size];
    }
    直接调用这个方法并不会引起end变量的变化,因此此时end还是为0,在调用workers.size的时候返回的是end的值,因此此时会被认为是0,因此此时会走下面这段代码:
     

    maxThreads是支持的最大线程数, curThreads是现在已有的线程数,很明显,如果maxThreads如果小于0,则没有限制,如果curThreads>=maxThreads,则已超过了限制,也不会重新生成新的线程,其它情况则会生成新的线程,看newWorkerThread方法如下:
        
    线程运行时会监查socket变量是否为空,是的话等待,之后运行其assign方法将获取到的socket赋予当前线程实例的socket变量后调用setSocketOptions及handler.process对其进行处理;setSocketOptions只设置一些socket的属性值,并无具体解析过程,真正的处理过程为后者,因此我们再来分析一下后者如何处理的;
    在Http11Protocol类的init方法中对JIoEndpoint对象进行了设置,其中便有设置其handler对象的调用,且其handler为Http11ConnectionHandler实例,但你如果看一下该类所实现的接口又会被雷到,其实现的接口为Handler,而该接口是JIoEndpoint里的一个内部公共接口,而Http11ConnectionHandler类是Http11Protocol的内部类,OMG.从代码风格来看似乎后期的这些处理与前期的一些解析工作大相径庭啊,应该是出自不同人之手的.废话少话,下面我们继续讲一下如何处理客户请求,看Http11ConnectionHandler.process(注意该类为Http11Protocol的内部类哦)方法,如下:
     

        recycledProcessors是一个ConcurrentLinkedQueue<Http11Processor>对象,这个类不熟,这里先不讲,看似不是很影响内容,看一下后面的createProcessor方法,如下:
         

        可以看到产生的是一个Http11Processor对象,然后最后调用其process方法,该对象又持有proto.endpoint对象,即JIoEndpoint类的实例,因为该类内容较多,因此对该类的分析将放到下一篇文章.

另外此处需要注意的是在Connector.start里调用protocolHandler.start()后还有一段代码如下:

这一段代码主要功能是初始化mapperListener,包含的工作主要是将找到的所有Host,Context,Wrapper等加入Mapper实例里,这样可以通过Mapper类统一匹配客户端请求是对应到哪个Context,Wrapper及Servlet进行处理的,我们后续可以在处理客户端请求2中看到相应的调用

原创粉丝点击