Tomcat的请求分发处理
一、Tomcat5的请求分发处理
tomcat4、5的socket分发处理非常简单,在HttpConnector的线程中,接收到一个Socket之后,从固定数量的HttpProcessor的线程队列中创建或取出一个HttpProcessor,对Socket进行处理。
1 //HttpConnector 2 public void run() { 3 // Loop until we receive a shutdown command 4 while (!stopped) { 5 Socket socket = null; 6 try { 7 socket = serverSocket.accept(); 8 if (connectionTimeout > 0) 9 socket.setSoTimeout(connectionTimeout); 10 socket.setTcpNoDelay(tcpNoDelay); 11 } catch (Exception ace) { 12 //...... 13 continue; 14 } 15 16 // Hand this socket off to an appropriate processor,processor.start() 17 HttpProcessor processor = createProcessor(); 18 if (processor == null) { 19 try { 20 log(sm.getString("httpConnector.noProcessor")); 21 socket.close(); 22 } catch (IOException e) { 23 ; 24 } 25 continue; 26 } 27 28 processor.assign(socket); 29 // The processor will recycle itself when it finishes 30 31 } 32 synchronized (threadSync) { 33 threadSync.notifyAll(); 34 } 35 36 }
HttpProcessor会线程复用,assign一个socket之后,notifyAll线程中的run方法中的wait,在run方法中开始对socket解析,创建Request和Response,调用相关的Container进行处理。
#HttpProcessor synchronized void assign(Socket socket) { // Wait for the Processor to get the previous Socket while (available) { try { wait(); } catch (InterruptedException e) { } } // Store the newly available Socket and notify our thread this.socket = socket; available = true; notifyAll(); if ((debug >= 1) && (socket != null)) log(" An incoming request is being assigned"); } /** * Await a newly assigned Socket from our Connector, or <code>null</code> * if we are supposed to shut down. */ private synchronized Socket await() { // Wait for the Connector to provide a new Socket while (!available) { try { wait(); } catch (InterruptedException e) { } } // Notify the Connector that we have received this Socket Socket socket = this.socket; available = false; notifyAll(); if ((debug >= 1) && (socket != null)) log(" The incoming request has been awaited"); return (socket); } /** * 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 (!stopped) { // Wait for the next socket to be assigned Socket socket = await(); if (socket == null) continue; // Process the request from this socket try { process(socket); } catch (Throwable t) { log("process.invoke", t); } // Finish up this request connector.recycle(this); } // Tell threadStop() we have shut ourselves down successfully synchronized (threadSync) { threadSync.notifyAll(); } }
二、Tomcat6的请求处理分发
Tomcat5只是对HttpProcessor采用了简单的线程池,并不涉及线程调度。而Tomcat6不仅保持原来的简单线程队列原有方式,还增加了目前使用的方式,即在原来的基础上添加了SocketProcessor任务线程池。针对每个socket创建一个SocketProecessor,交由系统线程池excutor进行执行,在SocketProcessor中再从HttpProcessor线程队列列获取一个HttpProcessor进行解析处理
/** * Process given socket. */ protected boolean processSocket(long socket) { try { if (executor == null) { getWorkerThread().assign(socket); } else { executor.execute(new SocketProcessor(socket)); } } catch (Throwable t) { // This means we got an OOM or similar creating a thread, or that // the pool and its queue are full log.error(sm.getString("endpoint.process.fail"), t); return false; } return true; } /** * This class is the equivalent of the Worker, but will simply use in an * external Executor thread pool. */ protected class SocketProcessor implements Runnable { protected long socket = 0; public SocketProcessor(long socket) { this.socket = socket; } public void run() { // Process the request from this socket if (handler.process(socket) == Handler.SocketState.CLOSED) { // Close socket and pool destroySocket(socket); socket = 0; } } } #Http11Processor public SocketState process(long socket) { Http11AprProcessor processor = recycledProcessors.poll(); try { if (processor == null) { processor = createProcessor(); } if (processor instanceof ActionHook) { ((ActionHook) processor).action(ActionCode.ACTION_START, null); } SocketState state = processor.process(socket); if (state == SocketState.LONG) { // Associate the connection with the processor. The next request // processed by this thread will use either a new or a recycled // processor. connections.put(socket, processor); proto.endpoint.getCometPoller().add(socket); } else { recycledProcessors.offer(processor); } return state; } recycledProcessors.offer(processor); return SocketState.CLOSED; }

浙公网安备 33010602011771号