try { // 设置状态为启动之前 setStateInternal(LifecycleState.STARTING_PREP, null, false); // 交给子类来具体的实现 startInternal(); // 子类处理完成后 if (state.equals(LifecycleState.FAILED)) { // This is a 'controlled' failure. The component put itself into the // FAILED state so call stop() to complete the clean-up. stop(); } elseif (!state.equals(LifecycleState.STARTING)) { // Shouldn't be necessary but acts as a check that sub-classes are // doing what they are supposed to. invalidTransition(Lifecycle.AFTER_START_EVENT); } else { setStateInternal(LifecycleState.STARTED, null, false); } } catch (Throwable t) { // This is an 'uncontrolled' failure so put the component into the // FAILED state and throw an exception. handleSubClassException(t, "lifecycleBase.startFail", toString()); } } }
publicstaticvoidmain(String args[]){ synchronized (daemonLock) { if (daemon == null) { // Don't set daemon until init() has completed Bootstrap bootstrap = new Bootstrap(); try { bootstrap.init(); //初始化 } catch (Throwable t) { handleThrowable(t); t.printStackTrace(); return; } daemon = bootstrap; } else { // When running as a service the call to stop will be on a new // thread so make sure the correct class loader is used to // prevent a range of class not found exceptions. Thread.currentThread().setContextClassLoader(daemon.catalinaLoader); } } //... }
publicclassContextConfigimplementsLifecycleListener{ /** * Process events for an associated Context. * * @param event The lifecycle event that has occurred */ @Override publicvoidlifecycleEvent(LifecycleEvent event){
// Identify the context we are associated with try { //从1、事件从取出当前组件,进行强转 context = (Context) event.getLifecycle(); } catch (ClassCastException e) { log.error(sm.getString("contextConfig.cce", event.getLifecycle()), e); return; }
// Process the event that has occurred //StandardContext的startInternal方法中触发CONFIGURE_START_EVENT事件 if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) { configureStart();//2、启动配置处理,解析处理web.xml配置等 } elseif (event.getType().equals(Lifecycle.BEFORE_START_EVENT)) { beforeStart(); } elseif (event.getType().equals(Lifecycle.AFTER_START_EVENT)) { // Restore docBase for management tools if (originalDocBase != null) { context.setDocBase(originalDocBase); } } elseif (event.getType().equals(Lifecycle.CONFIGURE_STOP_EVENT)) { configureStop(); } elseif (event.getType().equals(Lifecycle.AFTER_INIT_EVENT)) { init(); } elseif (event.getType().equals(Lifecycle.AFTER_DESTROY_EVENT)) { destroy(); } } protectedsynchronizedvoidconfigureStart(){ //略 //3、解析处理web.xml配置 webConfig(); //略 } //扫描适用于web应用程序的web.xml文件,并使用规范中定义的规则合并它们。 //对于全局web.xml文件,其中有重复的配置,最特定的级别优先。 //Ie应用程序的web.xml优先于主机级或全局web.xml文件。 protectedvoidwebConfig(){
if (context.getLogEffectiveWebXml()) { log.info("web.xml:\n" + webXml.toXml()); }
// Always need to look for static resources // Step 10. 寻找打包在jar中的静态资源 if (ok) { // Spec does not define an order. // Use ordered JARs followed by remaining JARs Set<WebXml> resourceJars = new LinkedHashSet<>(orderedFragments); for (WebXml fragment : fragments.values()) { if (!resourceJars.contains(fragment)) { resourceJars.add(fragment); } } processResourceJARs(resourceJars); // See also StandardContext.resourcesStart() for // WEB-INF/classes/META-INF/resources configuration }
// Default for Connector depends on this (deprecated) system property if (Boolean.parseBoolean(System.getProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "false"))) { encodedSolidusHandling = EncodedSolidusHandling.DECODE; } }
processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getProcessorCache()); eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getEventCache()); nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getBufferPool());
// Loop until we receive a shutdown command while (running) { while (paused && running) { if (state != AcceptorState.PAUSED) { pauseStart = System.nanoTime(); // Entered pause state state = AcceptorState.PAUSED; } if ((System.nanoTime() - pauseStart) > 1_000_000) { // Paused for more than 1ms try { if ((System.nanoTime() - pauseStart) > 10_000_000) { Thread.sleep(10); } else { Thread.sleep(1); } } catch (InterruptedException e) { // Ignore } } }
if (!running) { break; } state = AcceptorState.RUNNING;
try { //if we have reached max connections, wait countUpOrAwaitConnection();
SocketChannel socket = null; try { // Accept the next incoming connection from the server // socket //1、接收客户端连接通道 socket = serverSock.accept(); } catch (IOException ioe) { // We didn't get a socket countDownConnection(); if (running) { // Introduce delay if necessary errorDelay = handleExceptionWithDelay(errorDelay); // re-throw throw ioe; } else { break; } } // Successful accept, reset the error delay errorDelay = 0;
// Configure the socket if (running && !paused) { // setSocketOptions() will hand the socket off to // an appropriate processor if successful //2、将socket交给适当的处理器处理 if (!setSocketOptions(socket)) { closeSocket(socket); } } else { closeSocket(socket); } } catch (Throwable t) { ExceptionUtils.handleThrowable(t); log.error(sm.getString("endpoint.accept.fail"), t); } } state = AcceptorState.ENDED; } protectedbooleansetSocketOptions(SocketChannel socket){ // Process the connection try { //disable blocking, APR style, we are gonna be polling it //设置非阻塞 socket.configureBlocking(false); //2.1、获取客户端Socket 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(); } //2.2、向Poller注册socket,封装成PollerEvent,添加到队列 getPoller0().register(channel); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); try { log.error("",t); } catch (Throwable tt) { ExceptionUtils.handleThrowable(tt); } // Tell to close the socket returnfalse; } returntrue; } }
publicclassPollerimplementsRunnable{ private Selector selector; publicPoller()throws IOException { //打开选择器 this.selector = Selector.open(); } //注册socket,封装成PollerEvent,添加到队列 publicvoidregister(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.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); } //添加PollerEvent addEvent(r); } @Override publicvoidrun(){ // Loop until destroy() is called //线程循环调用处理socket事件 while (true) {
boolean hasEvents = false;
try { if (!close) { //1、轮询处理队列的PollerEvent,异步执行注册读取事件 hasEvents = events(); if (wakeupCounter.getAndSet(-1) > 0) { // If we are here, means we have other stuff to do // Do a non blocking select //非阻塞select keyCount = selector.selectNow(); } else { //阻塞select,当没有事件处理时,select方法会阻塞线程, 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) { ExceptionUtils.handleThrowable(x); log.error("",x); continue; } // Either we timed out or we woke up, process events first if (keyCount == 0) { hasEvents = (hasEvents | events()); } //4、获取事件进行处理 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(); //获取完事件处理完后,如果不移除,仍会存在,需要手动移除 iterator.remove(); NioSocketWrapper socketWrapper = (NioSocketWrapper) sk.attachment(); // Attachment may be null if another thread has called // cancelledKey() if (socketWrapper != null) { //5、调用processKey方法对有数据读写的socket进行处理 processKey(sk, socketWrapper); } }
// Process timeouts timeout(keyCount,hasEvents); }
getStopLatch().countDown(); } publicbooleanevents(){ boolean result = false;
PollerEvent pe = null; for (int i = 0, size = events.size(); i < size && (pe = events.poll()) != null; i++ ) { result = true; try { //2、异步运行PollerEvent,注册读取事件 pe.run(); pe.reset(); if (running && !paused) { eventCache.push(pe); } } catch ( Throwable x ) { log.error("",x); } }
publicabstractclassSocketProcessorBase<S> implementsRunnable{ @Override publicfinalvoidrun(){ synchronized (socketWrapper) { // It is possible that processing may be triggered for read and // write at the same time. The sync above makes sure that processing // does not occur in parallel. The test below ensures that if the // first event to be processed results in the socket being closed, // the subsequent events are not processed. if (socketWrapper.isClosed()) { return; } //3、处理请求 doRun(); } } }
// Link objects request.setResponse(response); response.setRequest(request);
// Set as notes //将HttpServletRequest到coyote.Request中 req.setNote(ADAPTER_NOTES, request); //将HttpServletResponse设置到coyote.Response中 res.setNote(ADAPTER_NOTES, response);
// 设置query参数编码 req.getParameters().setQueryStringCharset(connector.getURICharset()); } //... //解析和设置Catalina并配置特定的请求参数 boolean postParseSuccess = postParseRequest(req, request, res, response); if (postParseSuccess) { //check valves if we support async request.setAsyncSupported( connector.getService().getContainer().getPipeline().isAsyncSupported()); // Calling the container //Connector->StandardService->StandardEngine>StandardPipeline->StandardEngineValve.invoke connector.getService().getContainer().getPipeline().getFirst().invoke( request, response); } } }
// 根据请求的服务器名称,选择适当的子Host来处理此请求。如果没有找到匹配的Host,则返回适当的HTTP错误。 Host host = request.getHost(); if (host == null) { // HTTP 0.9 or HTTP 1.0 request without a host when no default host // is defined. // Don't overwrite an existing error if (!response.isError()) { //没有 response.sendError(404); } return; } if (request.isAsyncSupported()) { request.setAsyncSupported(host.getPipeline().isAsyncSupported()); }
// Ask this Host to process this request //StandardHost->AccessLogValve.invoke host.getPipeline().getFirst().invoke(request, response); } }
publicabstractclassAbstractAccessLogValveextendsValveBaseimplementsAccessLog{ @Override publicvoidinvoke(Request request, Response response)throws IOException, ServletException { if (tlsAttributeRequired) { // The log pattern uses TLS attributes. Ensure these are populated // before the request is processed because with NIO2 it is possible // for the connection to be closed (and the TLS info lost) before // the access log requests the TLS info. Requesting it now causes it // to be cached in the request. request.getAttribute(Globals.CERTIFICATES_ATTR); } if (cachedElements != null) { for (CachedElement element : cachedElements) { element.cache(request); } } //ErrorReportValve.invoke getNext().invoke(request, response); } }
finalclassStandardHostValveextendsValveBase{ @Override publicfinalvoidinvoke(Request request, Response response) throws IOException, ServletException { // Select the Context to be used for this Request Context context = request.getContext(); if (context == null) { // Don't overwrite an existing error if (!response.isError()) { response.sendError(404); } return; } //通知所有的javax.servlet.ServletRequestListener请求启动 if (!asyncAtStart && !context.fireRequestInitEvent(request.getRequest())) { // Don't fire listeners during async processing (the listener // fired for the request that called startAsync()). // If a request init listener throws an exception, the request // is aborted. return; } //... try { if (!response.isErrorReportRequired()) { //StandardPipeline->StandardContextValve.invoke context.getPipeline().getFirst().invoke(request, response); } } catch (Throwable t) { ExceptionUtils.handleThrowable(t); container.getLogger().error("Exception Processing " + request.getRequestURI(), t); // If a new error occurred while trying to report a previous // error allow the original error to be reported. if (!response.isErrorReportRequired()) { request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, t); throwable(request, response, t); } } } }
if (method.equals(METHOD_GET)) { long lastModified = getLastModified(req); if (lastModified == -1) { // servlet doesn't support if-modified-since, no reason // to go through further expensive logic doGet(req, resp); } else { long ifModifiedSince; try { ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE); } catch (IllegalArgumentException iae) { // Invalid date header - proceed as if none was set ifModifiedSince = -1; } if (ifModifiedSince < (lastModified / 1000 * 1000)) { // If the servlet mod time is later, call doGet() // Round down to the nearest second for a proper compare // A ifModifiedSince of -1 will always be less maybeSetLastModified(resp, lastModified); doGet(req, resp); } else { resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED); } }