在上一篇博文中,主要分析了tomcat的整體架構,通過上一篇的分析可以知道,tomcat主要有兩部分組成,分別為連接器(Connector)和容器(Container),本文介紹連接器(Connector),
一、Connector的主要功能
連接器主要用于對外交流,它負責接收外部的請求,然后把請求轉交給container進行處理,主要功能如下:
- 監聽網路請求、接受位元組流
- 根據應用層協議(HTTP or AJP)把接受到位元組流轉換成TomcatRequest
- 把TomcatReqeust轉換成ServletRequest
- 呼叫容器Servlet,得到ServletResponse
- 把ServletRespone轉換成TomcatResponse
- 把TomcatResponse轉化成位元組流,回傳給瀏覽器
基于以上詳細分析可知Connector的主要功能可以抽象為三點
- 網路監聽
- 協議決議處理
- 協議屏蔽轉換(tomcatRequest到servletReqeust轉換,servletResponse到tomcatResponse的轉換)
二、Connetor內部的組件
基于上述的分析,接下來具體看tomcat connector的代碼組件,主要有三個
- Endpoint-用于網路監聽
- Processor-用于協議決議處理
- Adapter-用于轉換,解耦connector和container
tomcat的類設計中增加了一個ProtocolHandler, 把Endpoint和Processor,Adapter封裝到了一起,先看一個整體組件圖,

三、Endpoint介紹
Endpoint是通信節點,實作了TCP/IP協議,包含兩個核心組件:
- Acceptor,主要用于監聽socket鏈接請求,
- SocketProcessor,用于處理接收到的 Socket 請求,實作了runnable介面,在run方法中會呼叫processor對socket請求進行處理,
Endpoint核心介面
public abstract class AbstractEndpoint<S> { protected Acceptor[] acceptors; protected abstract SocketProcessorBase<S> createSocketProcessor( SocketWrapperBase<S> socketWrapper, SocketEvent event); protected SynchronizedStack<SocketProcessorBase<S>> processorCache; /** * External Executor based thread pool. */ private Executor executor = null; }
這里面還有一個Executor, 這個是tomcat自己擴展的執行緒池,Acceptor監聽到socket請求后,創建SocketProcessor,由Executor來運行SocketProcessor,
Acceptor核心代碼:
protected class Acceptor extends AbstractEndpoint.Acceptor { @Override public void run() { while (running) { state = AcceptorState.RUNNING; try { //Accept the next incoming connection from the server SocketChannel socket = serverSock.accept();//監聽請求 //setSocketOptions() will hand the socket off to an appropriate processor if successful setSocketOptions(socket);//把請求傳給SocketProcessor } catch (Throwable t) { } } } }
setSocketOption最侄訓呼叫Endpoint的process方法,
Endpoint的process核心方法代碼如下:
public boolean processSocket(SocketWrapperBase<S> socketWrapper, SocketEvent event, boolean dispatch) { SocketProcessorBase<S> sc = processorCache.pop(); if (sc == null) { sc = createSocketProcessor(socketWrapper, event);//創建SocketProcessor } else { sc.reset(socketWrapper, event); } Executor executor = getExecutor(); executor.execute(sc);//交給執行緒池進行處理 return true; }
SocketProcessor的抽象類
public abstract class SocketProcessorBase<S> implements Runnable { protected SocketWrapperBase<S> socketWrapper; protected SocketEvent event; @Override public final void run() { synchronized (socketWrapper) { if (socketWrapper.isClosed()) { return; } doRun(); } } protected abstract void doRun(); }
SocketProcessor類
protected class SocketProcessor extends SocketProcessorBase<NioChannel> { public SocketProcessor(SocketWrapperBase<NioChannel> socketWrapper, SocketEvent event) { super(socketWrapper, event); } @Override protected void doRun() { NioChannel socket = socketWrapper.getSocket(); SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector()); getHandler().process(socketWrapper, SocketEvent.CONNECT_FAIL); } }
上面類中getHandler().process的具體實作,(Handler的介面由Endpoint的內部類進行定義,
protected static class ConnectionHandler<S> implements AbstractEndpoint.Handler<S> { private final Map<S, Processor> connections = new ConcurrentHashMap<>(); @Override public SocketState process(SocketWrapperBase<S> wrapper, SocketEvent status) { S socket = wrapper.getSocket(); Processor processor = connections.get(socket); return processor.process(wrapper, status); } }
至此、請求已經成功傳給可processor,
三、processor、adapter
processor是應用層協議比如HTTP的處理,他負責把請求傳給adapter,核心代碼如下,
@Override public SocketState service(SocketWrapperBase<?> socketWrapper) throws IOException { try { getAdapter().service(request, response); } catch (Exception e) { e.printStackTrace(); } return null; }
adapter解耦了connector和container的關系,主要負責把tomcatRequest轉換為servletRequest,然后最終呼叫container,核心代碼如下,
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res) throws Exception { Request request = (Request) req.getNote(ADAPTER_NOTES); Response response = (Response) res.getNote(ADAPTER_NOTES); if (request == null) { // Create objects request = connector.createRequest(); request.setCoyoteRequest(req); response = connector.createResponse(); response.setCoyoteResponse(res); } // Calling the container connector.getService().getContainer().getPipeline().getFirst().invoke(request, response); }
至此請求到達了container,我們的servlet會對進行業務邏輯處理,
四、細化流程

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/156148.html
標籤:Java
