zoukankan      html  css  js  c++  java
  • Tomcat处理请求流程

    1. Connector组件的Acceptor监听客户端套接字连接并接收Socket。
    2. 将连接交给线程池Executor处理,开始执行请求响应任务。
    3. Processor组件读取消息报文,解析请求行、请求体、请求头,封装成Request对象。
    4. Mapper组件根据请求行的URL值和请求头的Host值匹配由哪个Host容器、Context容器、Wrapper容器处理请求。
    5. CoyoteAdaptor组件负责将Connector组件和Engine容器关联起来,把生成的Request对象和响应对象Response传递到Engine容器中,调用 Pipeline。
    6. Engine容器的管道开始处理,管道中包含若干个Valve、每个Valve负责部分处理逻辑。执行完Valve后会执行基础的 Valve--StandardEngineValve,负责调用Host容器的Pipeline。
    7. Host容器的管道开始处理,流程类似,最后执行 Context容器的Pipeline。
    8. Context容器的管道开始处理,流程类似,最后执行 Wrapper容器的Pipeline。
    9. Wrapper容器的管道开始处理,流程类似,最后执行 Wrapper容器对应的Servlet对象的 处理方法

    Connector

    <Connector port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    

    ​ Connector用于接收请求并将请求封装成Request和Response来具体处理。最底层使用的是 Socket。Request和Response封装后交给Container(Servlet的容器)处理请求,Container处理后返回给Connector,最后由Socket返回给客户端。

    结构

    ​ Connector中具体是用 ProtocolHandler处理请求的,代表不同的连接类型。Http11Protocol使用普通Socket连接,Http11NioProtocol使用NioSocket连接。

    ​ ProtocolHandler中有三个重要的组件:

    • Endpoint:处理底层的Socket网络连接;
    • Processor:将Endpoint接收的Socket封装成Request;
    • Adapter:将封装后的Request交给Container处理;

    ​ Endpoint的抽象类 AbstractEndpoint定义了 Acceptor和 AsyncTimeout两个内部类 和 Handler接口。

    • Acceptor:监听请求;
    • AsyncTimeout:检查异步Request请求的超时;
    • Handler:处理接收的Socket,内部调用 Processor进行处理;
    public class Connector extends LifecycleMBeanBase  {
        public Connector() { this(null); }
        public Connector(String protocol) {
            // 根据 server.xml 中 Connector 属性 protocol 的值找合适的 className
            // 此处返回  org.apache.coyote.http11.Http11NioProtocol
            // 赋值给  ProtocolHandler
            setProtocol(protocol);
            ProtocolHandler p = null;
            try {
                Class<?> clazz = Class.forName(protocolHandlerClassName);
                // 反射生成 Http11NioProtocol 时,在构造函数中 生成了 NioEndpoint。
                p = (ProtocolHandler) clazz.getConstructor().newInstance();
            } finally {
                this.protocolHandler = p;
            }
            // 设置编码集
            if (Globals.STRICT_SERVLET_COMPLIANCE) {
                uriCharset = StandardCharsets.ISO_8859_1;
            } else {
                uriCharset = StandardCharsets.UTF_8;
            }
        }
        // 初始化操作
        @Override
        protected void initInternal() throws LifecycleException {
            super.initInternal();
            // 初始化是配置  CoyoteAdapter(Connector 作为参数)
            adapter = new CoyoteAdapter(this);
            // 协议处理器绑定 适配器
            protocolHandler.setAdapter(adapter);
            // 执行 协议处理器初始化操作
            protocolHandler.init();
        }
        // 使用此 连接器处理 请求
        @Override
        protected void startInternal() {
            // 验证端口
            if (getPort() < 0) { }
            // 设置生命周期状态值
            setState(LifecycleState.STARTING);
            // 调用 协议处理器 start 方法 
            protocolHandler.start();
        }
    }
    

    Http11NioProtocol

    ​ 主要包含 NioEndpoint组件和 Http11NioProcessor组件。启动时由NioEndpoint组件启动端口监听,连接到来被注册到NioChannel队列中,由Poller轮询器负责检测Channel的读写事件,并在创建任务后放入线程池中,线程池进行任务处理。

    public class Http11NioProtocol extends AbstractHttp11JsseProtocol<NioChannel> {
        // 创建了  NioEndpoint 类
        public Http11NioProtocol() {
            // 最终调用 AbstractProtocol 类
            super(new NioEndpoint());
        }
    }
    
    // 父类 AbstractProtocol
    public abstract class AbstractProtocol implements ProtocolHandler,MBeanRegistration {
        @Override
        public void init() throws Exception {
            // endpointName---"http-nio-8080": http-nio  +  8080 组成。
            String endpointName = getName();
            // 去掉 双引号
            endpoint.setName(endpointName.substring(1, endpointName.length()-1));
            // domain ==  catalina
            endpoint.setDomain(domain);
            // Endpoint的初始化操作
            // serverSocketChannel 绑定端口
            endpoint.init();
        }
        @Override
        public void start() throws Exception {
            // Endpoint 的 start 方法,重点
            // 创建 Executor、最大连接、开启 Poller thread
            endpoint.start();
            // 异步超时 线程,
            asyncTimeout = new AsyncTimeout();
            Thread timeoutThread = new Thread(asyncTimeout, getNameInternal() + "-AsyncTimeout");
            int priority = endpoint.getThreadPriority();
            if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
                priority = Thread.NORM_PRIORITY;
            }
            timeoutThread.setPriority(priority);
            timeoutThread.setDaemon(true);
            timeoutThread.start();
        }
    }
    
    // AsyncTimeout 实现 Runnable 接口
    protected class AsyncTimeout implements Runnable {
        private volatile boolean asyncTimeoutRunning = true;
        // 后台线程检查异步请求并在没有活动时触发超时。
        @Override
        public void run() {
            // 死循环,直到接收到 shutdown 命令
            while (asyncTimeoutRunning) {
                Thread.sleep(1000);
                long now = System.currentTimeMillis();
                for (Processor processor : waitingProcessors) {
                    processor.timeoutAsync(now);
                }
                // 循环,直到 Endpoint pause
                while (endpoint.isPaused() && asyncTimeoutRunning) {
                    Thread.sleep(1000);
                }
            }
        }
    }
    

    NioEndpoint

    ​ NioEndpoint是非阻塞IO的一个抽象,包含了:

    • LimitLatch:连接数控制器。
    • Acceptor:套接字连接并注册到Channel队列中。
    • Poller:轮询检查事件列表。
    • SocketProcessor:任务定义器。
    • Executor:负责处理套接字。
    // AbstractEndpoint
    public void init() throws Exception {
        if (bindOnInit) {
            bind();
            bindState = BindState.BOUND_ON_INIT;
        }
    }
    public final void start() throws Exception {
        // 判断是否绑定过
        if (bindState == BindState.UNBOUND) {
            bind();
            bindState = BindState.BOUND_ON_START;
        }
        startInternal();
    }
    
    // NioEndpoint
    @Override
    public void bind() throws Exception {
    	// 绑定 设置的端口
        if (!getUseInheritedChannel()) {
            serverSock = ServerSocketChannel.open();
            socketProperties.setProperties(serverSock.socket());
            InetSocketAddress addr = (getAddress()!=null?new InetSocketAddress(getAddress(),getPort()):new InetSocketAddress(getPort()));
            serverSock.socket().bind(addr,getAcceptCount());
        } else {
            // Retrieve the channel provided by the OS
            Channel ic = System.inheritedChannel();
            if (ic instanceof ServerSocketChannel) {
                serverSock = (ServerSocketChannel) ic;
            }
        }
        // 设置 阻塞模式
        serverSock.configureBlocking(true); //mimic APR behavior
        // 初始化 连接器、轮询器 默认线程数
        if (acceptorThreadCount == 0) {
            acceptorThreadCount = 1;
        }
        if (pollerThreadCount <= 0) {
            pollerThreadCount = 1;
        }
        setStopLatch(new CountDownLatch(pollerThreadCount));
        // 是否初始化 ssl
        initialiseSsl();
        selectorPool.open();
    }
    
    // 开启 NIO endpoint, 创建 acceptor, poller 线程.
    @Override
    public void startInternal() throws Exception {
    	// 设置 running 状态
        if (!running) {
            running = true;
            paused = false;
            // 默认 DEFAULT_SIZE:128  500
            processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                                                     socketProperties.getProcessorCache());
            eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                                                 socketProperties.getEventCache());
            nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
                                                  socketProperties.getBufferPool());
            if ( getExecutor() == null ) {
                createExecutor();
            }
    		// 初始化 连接数控制器,默认最大连接数 10000
            initializeConnectionLatch();
            // 开启 poller 线程, 默认 2
            // 检测到 事件后,交给 processor 处理
            pollers = new Poller[getPollerThreadCount()];
            for (int i=0; i<pollers.length; i++) {
                pollers[i] = new Poller();
                Thread pollerThread = new Thread(pollers[i], 
                                                 getName() + "-ClientPoller-"+i);
                pollerThread.setPriority(threadPriority);
                pollerThread.setDaemon(true);
                pollerThread.start();
            }
            // 开启 Acceptor 线程
            startAcceptorThreads();
        }
    }
    // AbstractEndpoint
    protected final void startAcceptorThreads() {
        int count = getAcceptorThreadCount();
        acceptors = new Acceptor[count];
        // 开启 Acceptor 线程
        for (int i = 0; i < count; i++) {
            // NioEndpoint 中实现
            acceptors[i] = createAcceptor();
            String threadName = getName() + "-Acceptor-" + i;
            acceptors[i].setThreadName(threadName);
            Thread t = new Thread(acceptors[i], threadName);
            t.setPriority(getAcceptorThreadPriority());
            t.setDaemon(getDaemon());
            t.start();
        }
    }
    

    连接数控制器-------LimitLatch

    处理流程图:

    ​ NIO模式下,Tomcat默认把阀门大小设置为 10000,可在 server.xml Connector节点下配置 maxConnections 属性修改。在连接数到达最大值后,仍可以接收客户端连接,直到操作系统接收队列被塞满。默认100,可在 Connector节点下 配置 acceptCount 属性修改。

    SocketChannel接收器--------Acceptor

    ​ Acceptor主要监听是否有客户端发来的连接并接收该连接,accept操作是阻塞的。此时返回 SocketChannel对象。Acceptor接收 SocketChannel 对象后要把它设置成非阻塞(后面对客户端连接才去非阻塞模式处理),接着设置套接字属性,封装成非阻塞通道对象。(NioChannel--HTTP、SecureNioChannel--HTTPS),最后将非阻塞通道对象注册到通道队列由 Poller 负责检测事件。

    // NioEndpoint
    protected class Acceptor extends AbstractEndpoint.Acceptor {
        @Override
        public void run() {
            int errorDelay = 0;
            // 死循环,知道收到  shutdown 命令
            while (running) {
                // Loop if endpoint is paused
                while (paused && running) {
                    state = AcceptorState.PAUSED;
                    Thread.sleep(50);
                }
                if (!running) {
                    break;
                }
                state = AcceptorState.RUNNING;
                try {
                    // 超过最大 连接,等待状态
                    countUpOrAwaitConnection();
                    // 接收从server来的下一个socket连接
                    SocketChannel socket = serverSock.accept();
                    // 正确接收 socket,重置 errorDelay
                    errorDelay = 0;
                    // Configure the socket
                    if (running && !paused) {
                        // 把 socket 交给合适的 处理器处理
                        if (!setSocketOptions(socket)) {
                            closeSocket(socket);
                        }
                    } else {
                        closeSocket(socket);
                    }
                }
            }
            state = AcceptorState.ENDED;
        }
    }
    protected boolean setSocketOptions(SocketChannel socket) {
        // 处理 socket
        try {
            // 设置 非阻塞模式
            socket.configureBlocking(false);
            Socket sock = socket.socket();
            socketProperties.setProperties(sock);
            NioChannel channel = nioChannels.pop();
            if (channel == null) {
                SocketBufferHandler bufhandler = new SocketBufferHandler(
                    socketProperties.getAppReadBufSize(),
                    socketProperties.getAppWriteBufSize(),
                    socketProperties.getDirectBuffer());
                // 判断是否开启 SSL 类型,生成不同类型的 Channel
                if (isSSLEnabled()) {
                    channel = new SecureNioChannel(socket, bufhandler, selectorPool, this);
                } else {
                    channel = new NioChannel(socket, bufhandler);
                }
            } else {
                channel.setIOChannel(socket);
                channel.reset();
            }
            // 获取 Poller,注册 成 Event 事件。
            getPoller0().register(channel);
        } catch (Throwable t) {
            // 出错了,就返回,进行 关闭 socket 处理
            return false;
        }
        return true;
    }
    

    轮询器----Poller

    ​ 需要同时对很多连接进行管理,通过不断遍历事件列表,对对应连接的相应事件作出处理。Poller内部依赖 JDK的Selector对象进行轮询,Selector会选择出待处理的事件,每轮询一次就选出若干需要处理的NioChannel,在NIO模式下,每次读取的数据时不确定的,每次读取的数据可能有请求头和请求行,每次只能尝试去解析报文,如果解析不成功则等待下次轮询读取更多数据后再次尝试,如果解析成功则做一些逻辑处理后对客户端响应,这些处理工作在任务定义器中定义。

    // 在 NioEndpoint startInternal方法中
    pollers = new Poller[getPollerThreadCount()];
    for (int i=0; i<pollers.length; i++) {
        pollers[i] = new Poller();
        Thread pollerThread = new Thread(pollers[i], getName() + "-ClientPoller-"+i);
        pollerThread.setPriority(threadPriority);
        pollerThread.setDaemon(true);
        pollerThread.start();
    }
    
    // NioEndpoint 类中定义
    public class Poller implements Runnable {
        private final SynchronizedQueue<PollerEvent> events =
            new SynchronizedQueue<>();
        private volatile boolean close = false;
        private Selector selector;
        @Override
        public void run() {
            // 死循环,直到调用 destory 法
            while (true) {
                boolean hasEvents = false;
                try {
                    if (!close) {
                        // 在 Acceptor 收到请求封装成 Socket 注册到 event 中
                        // 在轮询时从Event中取,进行处理
                        hasEvents = events();
                        if (wakeupCounter.getAndSet(-1) > 0) {
                            //if we are here, means we have other stuff to do
                            //do a non blocking select
                            keyCount = selector.selectNow();
                        } else {
                            keyCount = selector.select(selectorTimeout);
                        }
                        wakeupCounter.set(0);
                    }
                    if (close) {
                        events();
                        timeout(0, false);
                        try {
                            selector.close();
                        } catch (IOException ioe) {
                            log.error(sm.getString("endpoint.nio.selectorCloseFail"), ioe);
                        }
                        break;
                    }
                } catch (Throwable x) {
                    continue;
                }
                //either we timed out or we woke up, process events first
                if ( keyCount == 0 ) hasEvents = (hasEvents | events());
    
                Iterator<SelectionKey> iterator =
                    keyCount > 0 ? selector.selectedKeys().iterator() : null;
                // Walk through the collection of ready keys and dispatch
                // any active event.
                while (iterator != null && iterator.hasNext()) {
                    SelectionKey sk = iterator.next();
                    NioSocketWrapper attachment = (NioSocketWrapper)sk.attachment();
                    // 另一个线程调用了 cancelledKey 方法,attachment 可能为null
                    // 移除次事件,否则进行处理事件
                    if (attachment == null) {
                        iterator.remove();
                    } else {
                        iterator.remove();
                        processKey(sk, attachment);
                    }
                }
                // 处理超时情况
                timeout(keyCount,hasEvents);
            }
            getStopLatch().countDown();
        }
    
        protected void processKey(SelectionKey sk, NioSocketWrapper attachment) {
            try {
                if ( close ) {
                    cancelledKey(sk);
                } else if ( sk.isValid() && attachment != null ) {
                    if (sk.isReadable() || sk.isWritable() ) {
                        if ( attachment.getSendfileData() != null ) {
                            processSendfile(sk,attachment, false);
                        } else {
                            unreg(sk, attachment, sk.readyOps());
                            boolean closeSocket = false;
                            // Read goes before write
                            if (sk.isReadable()) {
                                // 在父类中定义
                                if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) {
                                    closeSocket = true;
                                }
                            }
                            if (!closeSocket && sk.isWritable()) {
                                if (!processSocket(attachment, SocketEvent.OPEN_WRITE, true)) {
                                    closeSocket = true;
                                }
                            }
                            if (closeSocket) {
                                cancelledKey(sk);
                            }
                        }
                    }
                } else {
                    //invalid key
                    cancelledKey(sk);
                }
            } catch ( CancelledKeyException ckx ) {
                cancelledKey(sk);
            }
        }
    }
    // AbstractEndpoint
    public boolean processSocket(SocketWrapperBase<S> socketWrapper,
                                 SocketEvent event, boolean dispatch) {
        try {
            if (socketWrapper == null) {
                return false;
            }
            // 从 栈中取一个
            SocketProcessorBase<S> sc = processorCache.pop();
            if (sc == null) {
       			// 没有就新建一个
                sc = createSocketProcessor(socketWrapper, event);
            } else {
                sc.reset(socketWrapper, event);
            }
            // 判断是否有 Executor,最终都是调用 Processor 的 run方法。
            Executor executor = getExecutor();
            // 见SocketProcessor
            if (dispatch && executor != null) {
                executor.execute(sc);
            } else {
                sc.run();
            }
        } catch (RejectedExecutionException ree) {
            return false;
        }
        return true;
    }
    

    任务定义器---SocketProcessor

    // 在上面的操作中,执行 run 方法时,
    // SocketProcessorBase
    @Override
    public final void run() {
        synchronized (socketWrapper) {
            if (socketWrapper.isClosed()) {
                return;
            }
            doRun();
        }
    }
    // 在 NioEndpoint 类中实现
    @Override
    protected void doRun() {
        NioChannel socket = socketWrapper.getSocket();
        SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
        int handshake = -1;
        if (handshake == 0) {
            SocketState state = SocketState.OPEN;
            // 处理请求
            if (event == null) {
                // 调用 Handler 转交给 Processor 去处理 process 方法,
                state = getHandler().process(socketWrapper, SocketEvent.OPEN_READ);
            } else {
                state = getHandler().process(socketWrapper, event);
            }
            if (state == SocketState.CLOSED) {
                close(socket, key);
            }
        }
        socketWrapper = null;
        event = null;
        //return to cache
        if (running && !paused) {
            processorCache.push(this);
        }
    }
    
    // AbstractProtocol
    protected static class ConnectionHandler<S> implements AbstractEndpoint.Handler<S> {
        @Override
        public SocketState process(SocketWrapperBase<S> wrapper, SocketEvent status) {
            if (wrapper == null) {
                return SocketState.CLOSED;
            }
            S socket = wrapper.getSocket();
            // 根据Socket获取具体协议的处理器
            Processor processor = connections.get(socket);
            // 如果process==null,尝试其它协议、新建等
            // SSL 支持
            processor.setSslSupport(
                wrapper.getSslSupport(getProtocol().getClientCertProvider()));
            // process 和 connection 关联
            connections.put(socket, processor);
            SocketState state = SocketState.CLOSED;
            do {
                // 处理
                state = processor.process(wrapper, status);
            } while ( state == SocketState.UPGRADING);
            // Make sure socket/processor is removed from the list of current
            connections.remove(socket);
            release(processor);
            return SocketState.CLOSED;
        }
    }
    
    // AbstractProcessorLight(公共父类)
    @Override
    public SocketState process(SocketWrapperBase<?> socketWrapper, SocketEvent status)
        throws IOException {
        SocketState state = SocketState.CLOSED;
        Iterator<DispatchType> dispatches = null;
        do {
            // 根据 SocketEvent 所处的 状态执行不同操作。
            if (dispatches != null) {
                DispatchType nextDispatch = dispatches.next();
                state = dispatch(nextDispatch.getSocketStatus());
            } else if (status == SocketEvent.DISCONNECT) {
                // Do nothing here, just wait for it to get recycled
            } else if (isAsync() || isUpgrade() || state == SocketState.ASYNC_END) {
                state = dispatch(status);
                if (state == SocketState.OPEN) {
                    state = service(socketWrapper);
                }
            } else if (status == SocketEvent.OPEN_WRITE) {
                state = SocketState.LONG;
            } else if (status == SocketEvent.OPEN_READ){
                state = service(socketWrapper);
            } else {
                state = SocketState.CLOSED;
            }
            if (state != SocketState.CLOSED && isAsync()) {
                state = asyncPostProcess();
            }
            if (dispatches == null || !dispatches.hasNext()) {
                dispatches = getIteratorAndClearDispatches();
            }
        } while (state == SocketState.ASYNC_END ||
                 dispatches != null && state != SocketState.CLOSED);
        return state;
    }
    
    // 调用具体协议的service方法处理请求
    @Override
    public SocketState service(SocketWrapperBase<?> socketWrapper) {
        // 判断状态
        while (!getErrorState().isError() && keepAlive && !isAsync() 
               && upgradeToken == null &&
               sendfileState == SendfileState.DONE && !endpoint.isPaused()) {
    
            // 解析request请求头
            try {
                if (!inputBuffer.parseRequestLine(keptAlive)) {
                    if (inputBuffer.getParsingRequestLinePhase() == -1) {
                        return SocketState.UPGRADING;
                    } else if (handleIncompleteRequestLineRead()) {
                        break;
                    }
                }
                if (endpoint.isPaused()) {
                    response.setStatus(503);
                    setErrorState(ErrorState.CLOSE_CLEAN, null);
                } else {
                    keptAlive = true;
                    request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount());
                    if (!inputBuffer.parseHeaders()) {
                        openSocket = true;
                        readComplete = false;
                        break;
                    }
                    if (!disableUploadTimeout) {
                        socketWrapper.setReadTimeout(connectionUploadTimeout);
                    }
                }
            } catch (IOException e) {
                setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e); break;
            } catch (Throwable t) {
                // 400 - Bad Request
                response.setStatus(400);
                setErrorState(ErrorState.CLOSE_CLEAN, t);
                // 日志调用处
                getAdapter().log(request, response, 0);
            }
            // Has an upgrade been requested?
            Enumeration<String> connectionValues = request.getMimeHeaders().values("Connection");
            boolean foundUpgrade = false;
            while (connectionValues.hasMoreElements() && !foundUpgrade) {
                foundUpgrade = connectionValues.nextElement().toLowerCase(
                    Locale.ENGLISH).contains("upgrade");
            }
            if (foundUpgrade) {
                // Check the protocol
                String requestedProtocol = request.getHeader("Upgrade");
                UpgradeProtocol upgradeProtocol = httpUpgradeProtocols.get(requestedProtocol);
                if (upgradeProtocol != null) {
                    if (upgradeProtocol.accept(request)) {
                        response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS);
                        response.setHeader("Connection", "Upgrade");
                        response.setHeader("Upgrade", requestedProtocol);
                        action(ActionCode.CLOSE,  null);
                        getAdapter().log(request, response, 0);
    
                        InternalHttpUpgradeHandler upgradeHandler =
                            upgradeProtocol.getInternalUpgradeHandler(
                            getAdapter(), cloneRequest(request));
                        UpgradeToken upgradeToken = new UpgradeToken(upgradeHandler, null, null);
                        action(ActionCode.UPGRADE, upgradeToken);
                        return SocketState.UPGRADING;
                    }
                }
            }
    
            if (!getErrorState().isError()) {
                rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
                try {
                    prepareRequest();
                } catch (Throwable t) {
                    // 500 - Internal Server Error
                    response.setStatus(500);
                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                    getAdapter().log(request, response, 0);
                }
            }
    
            if (maxKeepAliveRequests == 1) {
                keepAlive = false;
            } else if (maxKeepAliveRequests > 0 &&
                       socketWrapper.decrementKeepAlive() <= 0) {
                keepAlive = false;
            }
    
            // 通过 CoyotAdapte 处理 request
            if (!getErrorState().isError()) {
                try {
                    rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                    // 处理 request,见 CoyoteAdapter 解析
                    getAdapter().service(request, response);
                    if(keepAlive && !getErrorState().isError() && !isAsync() &&
                       statusDropsConnection(response.getStatus())) {
                        setErrorState(ErrorState.CLOSE_CLEAN, null);
                    }
                } catch (InterruptedIOException e) {
                    setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
                } catch (HeadersTooLargeException e) {
                    if (response.isCommitted()) {
                        setErrorState(ErrorState.CLOSE_NOW, e);
                    } else {
                        response.reset();
                        response.setStatus(500);
                        setErrorState(ErrorState.CLOSE_CLEAN, e);
                        response.setHeader("Connection", "close");
                    }
                } catch (Throwable t) {
                    // 500 - Internal Server Error
                    response.setStatus(500);
                    setErrorState(ErrorState.CLOSE_CLEAN, t);
                    getAdapter().log(request, response, 0);
                }
            }
    
            // Finish the handling of the request
            rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);
            if (!isAsync()) {
                endRequest();
            }
            rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT);
    
            // If there was an error, make sure the request is counted as
            // and error, and update the statistics counter
            if (getErrorState().isError()) {
                response.setStatus(500);
            }
    
            if (!isAsync() || getErrorState().isError()) {
                request.updateCounters();
                if (getErrorState().isIoAllowed()) {
                    inputBuffer.nextRequest();
                    outputBuffer.nextRequest();
                }
            }
            if (!disableUploadTimeout) {
                int soTimeout = endpoint.getConnectionTimeout();
                if(soTimeout > 0) {
                    socketWrapper.setReadTimeout(soTimeout);
                } else {
                    socketWrapper.setReadTimeout(0);
                }
            }
            rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
            sendfileState = processSendfile(socketWrapper);
        }
        rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
    }
    

    CoyoteAdapter

    @Override
    public void service(org.apache.coyote.Request req, org.apache.coyote.Response res) {
        Request request = (Request) req.getNote(ADAPTER_NOTES);
        Response response = (Response) res.getNote(ADAPTER_NOTES);
    	// request == null,新建并关联
        if (request == null) {
            // Create objects
            request = connector.createRequest();
            request.setCoyoteRequest(req);
            response = connector.createResponse();
            response.setCoyoteResponse(res);
            // Link objects
            request.setResponse(response);
            response.setRequest(request);
            // Set as notes
            req.setNote(ADAPTER_NOTES, request);
            res.setNote(ADAPTER_NOTES, response);
            // Set query string encoding
            req.getParameters().setQueryStringCharset(connector.getURICharset());
        }
    	// 设置请求头,告知网站是用何种语言或框架编写的
        // 默认false,Servlet/4.0 JSP/2.3xxxxxxxxxxxxxx
        if (connector.getXpoweredBy()) {
            response.addHeader("X-Powered-By", POWERED_BY);
        }
        boolean async = false;
        boolean postParseSuccess = false;
        req.getRequestProcessor().setWorkerThreadName(THREAD_NAME.get());
        try {
            // 请求映射、解析参数等操作。
            postParseSuccess = postParseRequest(req, request, res, response);
            if (postParseSuccess) {
                //check valves if we support async
                request.setAsyncSupported(
                    connector.getService()
                    		.getContainer()
                    		.getPipeline()
                    		.isAsyncSupported());
                // 由 Pipeline 处理流程,见Pipeline篇
                connector.getService()
                    		.getContainer()
                    		.getPipeline()
                    		.getFirst()
                    		.invoke(request, response);
            }
            // 异步处理
            if (request.isAsync()) {
                // 省略
            } else {
                request.finishRequest();
                response.finishResponse();
            }
        } finally {
            // 处理访问日志,见日志篇
            if (!async && postParseSuccess) {
                Context context = request.getContext();
                if (context != null) {
                    context.logAccess(request, response,
                         System.currentTimeMillis() - req.getStartTime(), false);
                }
            }
            req.getRequestProcessor().setWorkerThreadName(null);
            // 回收 request and response
            if (!async) {
                request.recycle();
                response.recycle();
            }
        }
    }
  • 相关阅读:
    C/C++多文件之间的变量定义
    PKU POJ 2186 Popular Cows 强连通分量
    重载函数
    ZOJ 2763 Prison Break
    201357 训练赛总结
    hdu 4467 Graph 构造
    201356 训练赛总结
    201353 NEERC 2012, Eastern subregional contest
    2013512 CF 183 总结
    一道动态规划
  • 原文地址:https://www.cnblogs.com/wl-blog/p/13866851.html
Copyright © 2011-2022 走看看