Tomcat源码---请求处理(接收,线程分配)一
一,在以上文章中tomcat启动已经完毕,接着要做的是消息的请求与响应
以下是tomcat文档中的详解
-----------------------------------------------------------
?
d) Tomcat receives a request on an HTTP port
? ?d1) The request is received by a separate thread which is waiting in the PoolTcpEndPoint?
? ? ? ? class. It is waiting for a request in a regular ServerSocket.accept() method.
? ? ? ? When a request is received, this thread wakes up.
? ?d2) The PoolTcpEndPoint assigns the a TcpConnection to handle the request.?
? ? ? ?It also supplies a JMX object name to the catalina container (not used I believe)
? ?d3) The processor to handle the request in this case is Coyote Http11Processor,?
? ? ? ?and the process method is invoked.
? ? ? ?This same processor is also continuing to check the input stream of the socket
? ? ? ?until the keep alive point is reached or the connection is disconnected.
? ?d4) The HTTP request is parsed using an internal buffer class (Coyote Http11 Internal Buffer)
? ? ? ?The buffer class parses the request line, the headers, etc and store the result in a?
? ? ? ?Coyote request (not an HTTP request) This request contains all the HTTP info, such
? ? ? ?as servername, port, scheme, etc.
? ?d5) The processor contains a reference to an Adapter, in this case it is the?
? ? ? ?Coyote Tomcat 5 Adapter. Once the request has been parsed, the Http11 processor
? ? ? ?invokes service() on the adapter. In the service method, the Request contains a?
? ? ? ?CoyoteRequest and CoyoteRespons (null for the first time)
? ? ? ?The CoyoteRequest(Response) implements HttpRequest(Response) and HttpServletRequest(Response)
? ? ? ?The adapter parses and associates everything with the request, cookies, the context through a?
? ? ? ?Mapper, etc
? ?d6) When the parsing is finished, the CoyoteAdapter invokes its container (StandardEngine)
? ? ? ?and invokes the invoke(request,response) method.
? ? ? ?This initiates the HTTP request into the Catalina container starting at the engine level
? ?d7) The StandardEngine.invoke() simply invokes the container pipeline.invoke()
? ?d8) By default the engine only has one valve the StandardEngineValve, this valve simply
? ? ? ?invokes the invoke() method on the Host pipeline (StandardHost.getPipeLine())
? ?d9) the StandardHost has two valves by default, the StandardHostValve and the ErrorReportValve
? ?d10) The standard host valve associates the correct class loader with the current thread
? ? ? ? It also retrives the Manager and the session associated with the request (if there is one)
? ? ? ? If there is a session access() is called to keep the session alive
? ?d11) After that the StandardHostValve invokes the pipeline on the context associated
? ? ? ? with the request.
? ?d12) The first valve that gets invoked by the Context pipeline is the FormAuthenticator
? ? ? ? valve. Then the StandardContextValve gets invoke.
? ? ? ? The StandardContextValve invokes any context listeners associated with the context.
? ? ? ? Next it invokes the pipeline on the Wrapper component (StandardWrapperValve)
? ?d13) During the invokation of the StandardWrapperValve, the JSP wrapper (Jasper) gets invoked
? ? ? ? This results in the actual compilation of the JSP.
? ? ? ? And then invokes the actual servlet.
e) Invokation of the servlet class
?
-----------------------------------------------------------
?
消息接收是从org.apache.tomcat.util.net.JIoEndpoint$Acceptor#run 这是tomcat接收请求的开始
?
/** * The background thread that listens for incoming TCP/IP connections and * hands them off to an appropriate processor. */ public void run() { // Process requests until we receive a shutdown signal while (running) { // Wait for the next socket to be assigned //以上所说的等待socket的赋值 Socket socket = await(); if (socket == null) continue; // Process the request from this socket //以下的handler.process(socket)才是真正的对socket开始进行处 //以上所做的只是分配而已,handler是在 //org.apache.coyote.http11.Http11Protocol(implements ProtocolHandler)#init if (!setSocketOptions(socket) || !handler.process(socket)) { // Close socket try { socket.close(); } catch (IOException e) { } } // Finish up this request socket = null; recycleWorkerThread(this);//进行回收线程 } }