Tomcat请求处理

1.用浏览器直接请求http://localhost:8080/,tomcat使用Acceptor监听端口,countUpOrAwaitConnection();控制最大连接数,接收请求socket = serverSock.accept();,获取缓存nioChannels中的NioChannel ,清空原有的buffer,给Socket 设置相应的属性, 

protected boolean setSocketOptions(SocketChannel socket) {
        // Process the connection
        try {
            //disable blocking, APR style, we are gonna be polling it
            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());
                if (isSSLEnabled()) {
                    channel = new SecureNioChannel(socket, bufhandler, selectorPool, this);
                } else {
                    channel = new NioChannel(socket, bufhandler);
                }
            } else {
                channel.setIOChannel(socket);
                channel.reset();
            }
            getPoller0().register(channel);
        } 
        return true;
    }
顺序选择初始化时创建的两个Poller中的其中一个 ,创建NioSocketWrapper(注册SelectionKey.OP_READ)和socket,Poller绑定在一起,从缓存eventCache取出PollerEvent或者新建一个进行包装,设置相应的监听事件OP_REGISTER,

 public void register(final NioChannel socket) {
            socket.setPoller(this);
            NioSocketWrapper ka = new NioSocketWrapper(socket, NioEndpoint.this);
            socket.setSocketWrapper(ka);
            ka.setPoller(this);
            ka.setReadTimeout(getSocketProperties().getSoTimeout());
            ka.setWriteTimeout(getSocketProperties().getSoTimeout());
            ka.setKeepAliveLeft(NioEndpoint.this.getMaxKeepAliveRequests());
            ka.setSecure(isSSLEnabled());
            ka.setReadTimeout(getConnectionTimeout());
            ka.setWriteTimeout(getConnectionTimeout());
            PollerEvent r = eventCache.pop();
            ka.interestOps(SelectionKey.OP_READ);//this is what OP_REGISTER turns into.
            if ( r==null) r = new PollerEvent(socket,ka,OP_REGISTER);
            else r.reset(socket,ka,OP_REGISTER);
            addEvent(r);
        }
放入SynchronizedQueue,并且通知selector,然后等待Poller线程拉取
private void addEvent(PollerEvent event) {
            events.offer(event);
            if ( wakeupCounter.incrementAndGet() == 0 ) selector.wakeup();
        }
2. Poller线程一直在执行keyCount = selector.select(selectorTimeout);,默认间隔时间是一秒,当收到通知后,这里就会返回1,而且他会一直执行events()

public boolean events() {
            boolean result = false;

            PollerEvent pe = null;
            for (int i = 0, size = events.size(); i < size && (pe = events.poll()) != null; i++ ) {
                result = true;
                try {
                    pe.run();
                    pe.reset();
                    if (running && !paused) {
                        eventCache.push(pe);
                    }
                } catch ( Throwable x ) {
                    log.error("",x);
                }
            }

            return result;
        }
从SynchronizedQueue中poll()取出请求,并且pe.run();清空后放入缓存eventCache.push(pe);以待下次请求直接使用,他主要是把SelectionKey和socketWrapper绑定在一起

 socket.getIOChannel().register(
                            socket.getPoller().getSelector(), SelectionKey.OP_READ, socketWrapper);

最后selector.selectedKeys()取出前面放入的NioSocketWrapper,这种方式类似一种缓冲机制

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();
                    // Attachment may be null if another thread has called
                    // cancelledKey()
                    if (attachment == null) {
                        iterator.remove();
                    } else {
                        iterator.remove();
                        processKey(sk, attachment);
                    }
                }//while
进行处理 processKey(sk, attachment);处理isReadable事件,

unreg(sk, attachment, sk.readyOps());
                            boolean closeSocket = false;
                            // Read goes before write
                            if (sk.isReadable()) {
                                if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) {
                                    closeSocket = true;
                                }
                            }

创建或从缓存取出SocketProcessor,把相关信息设置完毕后放入线程池异步执行,

public boolean processSocket(SocketWrapperBase<S> socketWrapper,SocketEvent event, boolean dispatch) {
        try {
           
            SocketProcessorBase<S> sc = processorCache.pop();
            if (sc == null) {
                sc = createSocketProcessor(socketWrapper, event);
            } else {
                sc.reset(socketWrapper, event);
            }
            Executor executor = getExecutor();
            if (dispatch && executor != null) {
                executor.execute(sc);
            } else {
                sc.run();
            }
        } 
        return true;
    }
3.处理Socket请求SocketProcessor .doRun()。先确认三次握手成功socket.isHandshakeComplete(),开始处理state = getHandler().process(socketWrapper, event);-》ConnectionHandler.process(),设置当前线程标志ContainerThreadMarker.set();创建getProtocol().createProcessor();或者从缓存recycledProcessors.pop();中取出Http11Processor,添加jmx属性register(processor);将处理器与连接关联 connections.put(socket, processor);-》state = processor.process(wrapper, status);-》 state = Http11Processor.service(socketWrapper);请求信息会有8个不同的 状态

 RequestInfo rp = request.getRequestProcessor();
        rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);

        // Setting up the I/O
        setSocketWrapper(socketWrapper);
        inputBuffer.init(socketWrapper);
        outputBuffer.init(socketWrapper);

解析请求头Http11InputBuffer.parseHeaders(),请求前处理prepareRequest();

rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
prepareRequest();
适配器CoyoteAdapter创建服务

 rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
                    getAdapter().service(request, response);
创建具体传到业务端的request,response,最后用HttpServletRequest包装一下,就是我们开发业务系统时常用的属性

// Create objects
            request = connector.createRequest();
            request.setCoyoteRequest(req);
            response = connector.createResponse();
            response.setCoyoteResponse(res);

            // Link objects
            request.setResponse(response);
            response.setRequest(request);
解析设置具体配置请求参数postParseSuccess = postParseRequest(req, request, res, response); 查找对应的各级容器,设置 sessionID等信息

 connector.getService().getMapper().map(serverName, decodedURI, version, request.getMappingData());

 // Virtual host mapping
        MappedHost[] hosts = this.hosts;
        MappedHost mappedHost = exactFindIgnoreCase(hosts, host);
 // Context mapping
        ContextList contextList = mappedHost.contextList;
        MappedContext[] contexts = contextList.contexts;
        int pos = find(contexts, uri);
 // Wrapper mapping
        if (!contextVersion.isPaused()) {
            internalMapWrapper(contextVersion, uri, mappingData);
        }

开始依次通过各级容器的管道invoke处理

connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);

StandardEngineValve-》AccessLogValve父类AbstractAccessLogValve-》ErrorReportValve-》StandardHostValve-》StandardContextValve这里会更改类加载器系统加载器为自定义加载器ParallelWebappClassLoader-》StandardWrapperValve分配servlet实例来处理此请求servlet = wrapper.allocate();为这个请求创建过滤器链,过滤器链需要从context容器获取FilterMap filterMaps[] = context.findFilterMaps();

ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);

4.在ApplicationFilterChain类中执行具体请求,传递HttpServletRequest和HttpServletResponse

  filterChain.doFilter(request.getRequest(), response.getResponse());
如果有过滤器依次执行filter.doFilter(request, response, this);
最后调用 servlet.service(request, response);-》HttpServlet.service(request, response);SpringMVC的DispatcherServlet就是实现的这个地方,执行完之后清理ThreadLocal中的缓存, 以及一些其他的对象使用wrapper.deallocate(servlet);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值