Tomcat最底層是使用Socket來進行鏈接的,而Connector的做用就是將接受到的請求轉換爲Request和Response。Request和Response是按照HTTP協議來封裝的,封裝完成後就交給Container進行處理。Container處理完成後又返回給Connector,由Connector返給客戶端前端
Connector主要是經過ProtocolHandler來處理請求的。不用的ProtocolHandler表明不一樣的鏈接類型。例如Http11Protocal使用普通的socket(同步處理),http11NioProtocal使用的NioSocket來連接。ProtocolHandler裏面有3個很重要的組件:java
<!-- 定義一個Connector,在8080端口箭頭HTTP的請求 --> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> <!-- 定義一個Connector,在8009端口箭頭AJP的請求 --> <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
在server.xml中就有Connector的配置。圖中配置了監聽HTTP請求和AJP請求apache
ProtocolHandler有一個抽象實現類AbstractProtocal,下面有3個子類,分別是對Ajp,Http,spdy協議的實現服務器
在Connector中默認是使用org.apache.coyote.http11.Http11NioProtocol。app
Endpoint用於處理具體的鏈接和數據傳輸,實現是比較複雜的。NioEndpoint集成AnstractEndpoint,AnstractEndpoint也是一個模板類,例如start()方法在AnstractEndpoint中,其中bind()方法由子類去實現socket
public final void start() throws Exception { if (bindState == BindState.UNBOUND) { bind(); bindState = BindState.BOUND_ON_START; } startInternal(); } public abstract void bind() throws Exception;
NioEndpoint的bind()方法就是初始化ServerSocketChannel和Selectorgoogle
public void bind() throws Exception { serverSock = ServerSocketChannel.open(); socketProperties.setProperties(serverSock.socket()); InetSocketAddress addr = (getAddress()!=null?new InetSocketAddress(getAddress(),getPort()):new InetSocketAddress(getPort())); serverSock.socket().bind(addr,getBacklog()); serverSock.configureBlocking(true); //mimic APR behavior serverSock.socket().setSoTimeout(getSocketProperties().getSoTimeout()); // Initialize thread count defaults for acceptor, poller if (acceptorThreadCount == 0) { // FIXME: Doesn't seem to work that well with multiple accept threads acceptorThreadCount = 1; } if (pollerThreadCount <= 0) { //minimum one poller thread pollerThreadCount = 1; } stopLatch = new CountDownLatch(pollerThreadCount); // Initialize SSL if needed initialiseSsl(); selectorPool.open(); }
啓動是在startInternal()方法中,主要作了2個事情,初始化Poller線程和Accept線程,Accept負責接收Socket請求,而後具體的處理方法是在Poller線程中。(Accept和Poller是內部類)spa
public void startInternal() throws Exception { if (!running) { running = true; paused = false; processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getProcessorCache()); eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getEventCache()); nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE, socketProperties.getBufferPool()); // Create worker collection if ( getExecutor() == null ) { createExecutor(); } initializeConnectionLatch(); // Start poller threads pollers = new Poller[getPollerThreadCount()]; for (int i=0; i<pollers.length; i++) { pollers[i] = new Poller(); Thread pollerThread = new Thread(pollers[i], getName() + "-ClientPoller-"+i); pollerThread.setPriority(threadPriority); pollerThread.setDaemon(true); pollerThread.start(); } startAcceptorThreads(); } }
主要用於處理應用層協議(如HTTP),分別由3個基本協議對應3個基本的抽象類線程
Adapter只有一個實現類,就是CoyoteAdapter類。code