Tomcat源码走读 07-tomcat处理请求

07-tomcat处理请求

在上一章06-tomcat的容器启动过程中,我们知道了处理请求的逻辑在Accptor里面。本章我们直接从这里往后描述。

1. JIoEndpoint.processSocket()

protected boolean processSocket(Socket socket) {
        try {
            SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);
            wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
            wrapper.setSecure(isSSLEnabled());
            if (!running) {
                return false;
            }
            getExecutor().execute(new SocketProcessor(wrapper));
        } catch (RejectedExecutionException x) {
            return false;
        } catch (Throwable t) {
            return false;
        }
        return true;
    }

getExecutor()在上一章中讲过是创建了一个默认200最大线程数的线程池,tomcat使用自己的TaskQueue“修复”了线程池的无界队列最大线程池无效的“bug”,具体可以自行百度。
所以这里是开启了一个SocketProcessor线程继续执行请求。从而实现并发处理请求的业务。

2. SocketProcessor.run()

public void run() {
            boolean launch = false;
            synchronized (socket) {
                try {
                    SocketState state = SocketState.OPEN;
                    try {
                        serverSocketFactory.handshake(socket.getSocket()); //在我们当前逻辑中是DefaultServerSocketFactory.handshake(),这里是一个空实现
                    } catch (Throwable t) {
                    }
                    if ((state != SocketState.CLOSED)) {
                        if (status == null) { //因为我们是从一个参数的构造进入SocketProcessor,所以status为null
                            state = handler.process(socket, SocketStatus.OPEN_READ); //处理请求
                        } else {
                            state = handler.process(socket,status);
                        }
                    }
                    if (state == SocketState.CLOSED) {
                        countDownConnection();
                        try {
                            socket.getSocket().close();
                        } catch (IOException e) {
                        }
                    } else if (state == SocketState.OPEN ||
                            state == SocketState.UPGRADING ||
                            state == SocketState.UPGRADING_TOMCAT  ||
                            state == SocketState.UPGRADED){
                        socket.setKeptAlive(true);
                        socket.access();
                        launch = true;
                    } else if (state == SocketState.LONG) {
                        socket.access();
                        waitingRequests.add(socket);
                    }
                } finally {
            }
            socket = null;
            // Finish up this request
        }
2.1. AbstractProtocol.process()
public SocketState process(SocketWrapper<S> wrapper,
                SocketStatus status) {
            S socket = wrapper.getSocket();
            Processor<S> processor = connections.get(socket);
            wrapper.setAsync(false);
            try {
                if (processor == null) {
                    processor = recycledProcessors.poll();
                }
                if (processor == null) {
                    processor = createProcessor(); //创建一个Http11Processor
                }
                initSsl(wrapper, processor); //未用到ssl,暂不关注
                SocketState state = SocketState.CLOSED;
                do {
                    if (status == SocketStatus.DISCONNECT &&
                            !processor.isComet()) {
                    } else if (processor.isAsync() ||
                            state == SocketState.ASYNC_END) {
                        state = processor.asyncDispatch(status);
                    } else if (processor.isComet()) {
                        state = processor.event(status);
                    } else if (processor.getUpgradeInbound() != null) {
                        state = processor.upgradeDispatch();
                    } else if (processor.isUpgrade()) {
                        state = processor.upgradeDispatch(status);
                    } else { //上面createProcessor的processor没有设置条件中的值,故直接走的这里
                        state = processor.process(wrapper);
                    }
                    if (state != SocketState.CLOSED && processor.isAsync()) {
                        state = processor.asyncPostProcess();
                    }
                    if (state == SocketState.UPGRADING) {
                        HttpUpgradeHandler httpUpgradeHandler =
                                processor.getHttpUpgradeHandler();
                        release(wrapper, processor, false, false);
                        processor = createUpgradeProcessor(
                                wrapper, httpUpgradeHandler);
                        wrapper.setUpgraded(true);
                        connections.put(socket, processor);
                        httpUpgradeHandler.init((WebConnection) processor);
                    } else if (state == SocketState.UPGRADING_TOMCAT) {
                        org.apache.coyote.http11.upgrade.UpgradeInbound inbound =
                                processor.getUpgradeInbound();
                        release(wrapper, processor, false, false);
                        processor = createUpgradeProcessor(wrapper, inbound);
                        inbound.onUpgradeComplete();
                    }
                        state == SocketState.UPGRADING ||
                        state == SocketState.UPGRADING_TOMCAT);
                if (state == SocketState.LONG) {
                    connections.put(socket, processor);
                    longPoll(wrapper, processor);
                } else if (state == SocketState.OPEN) {
                    connections.remove(socket);
                    release(wrapper, processor, false, true);
                } else if (state == SocketState.SENDFILE) {
                    connections.remove(socket);
                    release(wrapper, processor, false, false);
                } else if (state == SocketState.UPGRADED) {
                    connections.put(socket, processor);
                    if (status != SocketStatus.OPEN_WRITE) {
                        longPoll(wrapper, processor);
                    }
                } else {
                    connections.remove(socket);
                    if (processor.isUpgrade()) {
                        processor.getHttpUpgradeHandler().destroy();
                    } else if (processor instanceof org.apache.coyote.http11.upgrade.UpgradeProcessor) {
                    } else {
                        release(wrapper, processor, true, false);
                    }
                }
                return state;
            } catch(java.net.SocketException e) {
            } catch (java.io.IOException e) {
            } catch (Throwable e) {
            }
            connections.remove(socket);
            if (!(processor instanceof org.apache.coyote.http11.upgrade.UpgradeProcessor)
                    && !processor.isUpgrade()) {
                release(wrapper, processor, true, false);
            }
            return SocketState.CLOSED;
        }
2.2 AbstractHttp11Processor.process()
public SocketState process(SocketWrapper<S> socketWrapper)
        throws IOException {
        RequestInfo rp = request.getRequestProcessor();
        rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
        setSocketWrapper(socketWrapper);
//input和output都在Http11Processor的构造里面创建的
        getInputBuffer().init(socketWrapper, endpoint); //把socket的inputStream赋值给processor
        getOutputBuffer().init(socketWrapper, endpoint);//把socket的outputStream赋值给processor
        error = false;
        keepAlive = true;
        comet = false;
        openSocket = false;
        sendfileInProgress = false;
        readComplete = true;
        if (endpoint.getUsePolling()) { //JIoEndpoint不支持,直接返回false
            keptAlive = false;
        } else {
            keptAlive = socketWrapper.isKeptAlive();  //默认false
        }

        if (disableKeepAlive()) { //如果当前请求数,也就是当前线程池活跃线程除以最大线程*100大于默认75,返回true。 最大线程之前讲过默认为200。所以就是大于同时150个请求。
            socketWrapper.setKeepAliveLeft(0);
        }

        while (!error && keepAlive && !comet && !isAsync() &&
                upgradeInbound == null &&
                httpUpgradeHandler == null && !endpoint.isPaused()) {
            try {
                setRequestLineReadTimeout(); //调整超时时间
                if (endpoint.isPaused()) {
                    response.setStatus(503);
                    error = true;
                } else {
                    if (request.getStartTime() < 0) {
                        request.setStartTime(System.currentTimeMillis());
                    }
                    keptAlive = true;
                    // Set this every time in case limit has been changed via JMX
                    request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount());
                    // Currently only NIO will ever return false here
                    if (!getInputBuffer().parseHeaders()) { //解析请求头
                        openSocket = true;
                        readComplete = false;
                        break;
                    }
                }
            } catch (IOException e) {
                break;
            } catch (Throwable t) {
            }

            if (!error) {
                // Setting up filters, and parse some request headers
                rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
                try {
                    prepareRequest(); //预处理请求。
                } catch (Throwable t) {
                }
            }
            if (maxKeepAliveRequests == 1) {
                keepAlive = false;
            } else if (maxKeepAliveRequests > 0 &&
                    socketWrapper.decrementKeepAlive() <= 0) {
                keepAlive = false;
            }
            // Process the request in the adapter
            if (!error) {
                try {
                    rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                    adapter.service(request, response); //开始处理请求
                    if(keepAlive && !error) { // Avoid checking twice.
                        error = response.getErrorException() != null ||
                                (!isAsync() &&
                                statusDropsConnection(response.getStatus()));
                    }
                    setCometTimeouts(socketWrapper);
                } catch (InterruptedIOException e) {
                } catch (HeadersTooLargeException e) {
                } catch (Throwable t) {
                }
            }

            // Finish the handling of the request
            rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);

            if (!isAsync() && !comet) {
                if (error) {
                    getInputBuffer().setSwallowInput(false);
                }
                if (response.getStatus() < 200 || response.getStatus() > 299) {
                    if (expectation) {
                        getInputBuffer().setSwallowInput(false);
                        keepAlive = false;
                    }
                }
                endRequest();
            }

            rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT);
            if (error) {
                response.setStatus(500);
            }
            request.updateCounters();
            if (!isAsync() && !comet || error) {
                getInputBuffer().nextRequest();
                getOutputBuffer().nextRequest();
            }
            if (!disableUploadTimeout) {
                if(endpoint.getSoTimeout() > 0) {
                    setSocketTimeout(endpoint.getSoTimeout());
                } else {
                    setSocketTimeout(0);
                }
            }
            rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
            if (breakKeepAliveLoop(socketWrapper)) {
                break;
            }
        }
        rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
        if (error || endpoint.isPaused()) {
            return SocketState.CLOSED;
        } else if (isAsync() || comet) {
            return SocketState.LONG;
        } else if (isUpgrade()) {
            return SocketState.UPGRADING;
        } else if (getUpgradeInbound() != null) {
            return SocketState.UPGRADING_TOMCAT;
        } else {
            if (sendfileInProgress) {
                return SocketState.SENDFILE;
            } else {
                if (openSocket) {
                    if (readComplete) {
                        return SocketState.OPEN;
                    } else {
                        return SocketState.LONG;
                    }
                } else {
                    return SocketState.CLOSED;
                }
            }
        }
    }

request和response是在new Http11Processor的时候在其父类的AbstractProcessor的构造方法中初始化的。如下:

public AbstractProcessor(AbstractEndpoint endpoint) {
        this.endpoint = endpoint;
        asyncStateMachine = new AsyncStateMachine<S>(this);
        request = new Request();
        response = new Response();
        response.setHook(this);
        request.setResponse(response);
    }

CoyoteAdapter.service()处理请求如下:

public void service(org.apache.coyote.Request req,
                        org.apache.coyote.Response res)
        throws Exception {

        Request request = (Request) req.getNote(ADAPTER_NOTES); //这就是httpservletRequest
        Response response = (Response) res.getNote(ADAPTER_NOTES);
        boolean comet = false;
        boolean async = false;
        try {
            req.getRequestProcessor().setWorkerThreadName(Thread.currentThread().getName());
    //解析请求参数,cookie,session等等请求信息。
            boolean postParseSuccess = postParseRequest(req, request, res, response);
            if (postParseSuccess) {
                request.setAsyncSupported(connector.getService().getContainer().getPipeline().isAsyncSupported());
                connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
                 //真正处理请求的地方
            }
        } catch (IOException e) {
        } finally {
        }
    }

上面处理请求的地方,根据debug最终调用到StandardWrapperValue.invoke()里面。

public final void invoke(Request request, Response response)
        throws IOException, ServletException {
        Servlet servlet = null;
        try {
            if (!unavailable) {
                servlet = wrapper.allocate(); //获取StandardWrapper的servlet对象,springmvc就是dispatcherServlet
            }
        } catch (UnavailableException e) {
        } catch (ServletException e) {
        } catch (Throwable e) {
        }
     
        ApplicationFilterFactory factory =
            ApplicationFilterFactory.getInstance();
        ApplicationFilterChain filterChain =
            factory.createFilterChain(request, wrapper, servlet); //创建一个包装servlet的filterChain。
        try {
            if ((servlet != null) && (filterChain != null)) {
                if (context.getSwallowOutput()) {
                } else {
                    if (request.isAsyncDispatching()) {
                    } else if (comet) {
                    } else {
                        filterChain.doFilter
                            (request.getRequest(), response.getResponse()); //调用filter和servlet。
                    }
                }

            }
        } catch (ClientAbortException e) {
        } catch (IOException e) {
        } catch (UnavailableException e) {
        } catch (ServletException e) {
        } catch (Throwable e) {
        }
        if (filterChain != null) {
            if (request.isComet()) {
                filterChain.reuse();
            } else {
                filterChain.release();
            }
        }
        try {
            if (servlet != null) {
                wrapper.deallocate(servlet);
            }
        } catch (Throwable e) {
        }
    }

ApplicationFilterChain.doFilter() ==》 internalDoFilter()

private void internalDoFilter(ServletRequest request, 
                                  ServletResponse response)
        throws IOException, ServletException {
        if (pos < n) {
            ApplicationFilterConfig filterConfig = filters[pos++];
            Filter filter = null;
            try {
                filter = filterConfig.getFilter();
                if( Globals.IS_SECURITY_ENABLED ) {
                    final ServletRequest req = request;
                    final ServletResponse res = response;
                    Principal principal = 
                        ((HttpServletRequest) req).getUserPrincipal();

                    Object[] args = new Object[]{req, res, this};
                    SecurityUtil.doAsPrivilege
                        ("doFilter", filter, classType, args, principal);
                    
                } else {  
                    filter.doFilter(request, response, this); //调用filter。filter中chain.doFilter()在继续递归调用
                }
            } catch (IOException e) {
            } catch (ServletException e) {
            } catch (RuntimeException e) {
            } catch (Throwable e) {
            }
            return;
        }

        // We fell off the end of the chain -- call the servlet instance
        try {
            if ((request instanceof HttpServletRequest) &&
                (response instanceof HttpServletResponse)) {
                if( Globals.IS_SECURITY_ENABLED ) {
                    final ServletRequest req = request;
                    final ServletResponse res = response;
                    Principal principal = 
                        ((HttpServletRequest) req).getUserPrincipal();
                    Object[] args = new Object[]{req, res};
                    SecurityUtil.doAsPrivilege("service",
                                               servlet,
                                               classTypeUsedInService, 
                                               args,
                                               principal);   
                } else {  
                    servlet.service(request, response); //最后一个filter走完,不会进入上面的filter的if语句了,就会走到这里。调用我们熟悉的Servlet.service()方法,也就是把请求传达到我们的servlet了。
                }
            } else {
                servlet.service(request, response); 
            }
        } catch (IOException e) {
        } catch (ServletException e) {
        } catch (RuntimeException e) {
        } catch (Throwable e) {
        } finally {
        }
    }

至此,一个完整的http请求到servlet的过程就已完成了。

总结:
处理请求过程就是在解析和封装socket的输入输出流。
默认最大有200个线程处理请求,最大连接数默认等于最大线程数。
filter的调用是通过递归实现的,所以如果我们在doFilter里面不放行,也就是手动调用chain.doFilter()的话,就不会继续执行后面的filter,也就不能跳出filter的位置那个if判断直接return掉前面所有,所以就不能在执行servlet.service()方法,也就是调用到我们的servlet。
之前讲过endpoint的属性基本都可以通过Connector节点指定,所以我们也可以定义自己想要的最大处理请求线程,最大连接数等等,比如:

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" maxThreads="300" maxConnections="250"                 
                acceptorThreadCount="3"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值