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();
            }
        }
    }
  • 相关阅读:
    oracle 如何用触发器实现更新刚插入的数据
    数据库好论坛
    不同的用户导入数据库
    用函数式编程技术编写优美的 JavaScript
    使用GridView自带的ToolTip隐藏过长的数据
    含有dropdownlist的gridview增删改查
    数据分析
    数据分析
    xshell链接vbox 上 nat 方式链接虚拟机
    测试开发方法概述
  • 原文地址:https://www.cnblogs.com/wl-blog/p/13866851.html
Copyright © 2011-2022 走看看