天天看點

Tomcat connector 實作原理

Bootstrap.main()->Bootstrap.init()

Tomcat connector 實作原理

bootstrap.init() 方法中設定catalinaDaemon

建立 Connector 對象

Bootstrap.main()->Bootstrap.start()->Catalina.start()->Catalina.load()->Catalina.createStartDigester()

createStartDigester() 方法

Tomcat connector 實作原理

1. 建立connector對象,并判斷server.xml 中是否配置線程池,如果配置線程池則建立線程池

Tomcat connector 實作原理
  1. 為connector對象設定除executor外的其它屬性資訊
  2. 把目前connector添加到StandardService.connectors 數組中。

Connector

構造

Tomcat connector 實作原理

通過protocol協定來判斷使用那個protocolHandler。

setProtocol 方法

Tomcat connector 實作原理

tomcat 預設配置 是以BIO的模式啟動的,預設會調用org.apache.coyote.http11.Http11Protocol。

下面我們以Http11Protocol來分析Connector。

startInternal() 方法

Tomcat connector 實作原理

1. 設定tomcat狀态為,正在啟動

2. 啟動 connector。

Http11Protocol

Tomcat connector 實作原理
  1. 在構造方法中建立JIoEndpoint和Http11ConnectionHandler對象
  2. 設定 socket 參數

AbstractEndpoint.start() 方法

JIoEndpoint 繼承 AbstractEndpoint

Tomcat connector 實作原理

JIoEndpoint .bind() 方法

Tomcat connector 實作原理

在這建立connector的socket服務,使用serverSocket監聽入站連接配接。

JIoEndpoint.startInternal() 方法

Tomcat connector 實作原理

1. 判斷線程池是否為空,如果為空則建立預設的線程池。(server.xml的connector中配置的線程池)

2. 根據server.xml中的connector中的acceptorThreadCount屬性來确定建立幾個接受請求處理的線程。

Acceptor類,負責處理接受用戶端請求的處理。

server.xml 中配置如下:

acceptorThreadCount 個數建議和CPU的個數一緻。

createExecutor() 方法

Tomcat connector 實作原理

預設建立的線程池,最小線程數為10,最大線程數為200,空閑時間為60秒,隊列為LinkedBlockingQueue,隊列大小預設為Ineteger.MAX_VALUE。

這裡需要注意的是,如果隊列中的元素沒有存滿,那麼線程的數量一直會是10,而不會自動擴大到200。是以建議大家自己設定一個線程池,而不要用預設的

Acceptor 類

Acceptor.run() 方法
Tomcat connector 實作原理
  1. 擷取之前建立的serverSocket。

    2.設定socket的參數

  2. 調用processSocket 處理請求的socket

processSocket() 方法

Tomcat connector 實作原理

把socket封裝成SocketWrapper對象 傳給SocketProcessor對象,并送出給線程池處理。

SocketProcessor

負責解析http協定資訊。

SOcketProcessor重要屬性

Tomcat connector 實作原理

inputBuffer:包裝socket的inputStream,并解析http協定資訊。

outputBuffer:包裝socket的outputStream,負責響應使用者的資料。

run() 方法

Tomcat connector 實作原理

在process方法中處了解析http協定資訊。

Http11Processor.process() 方法

Http11Protocol.process()->Http11Processor.process() 代碼如下:

Tomcat connector 實作原理

擷取socket的輸入流和輸出流

Http11Processor構造方法

Tomcat connector 實作原理

在這裡,構造Request和Response對象。

解析http協定
Tomcat connector 實作原理

解析完後的資料存儲到 AbstractInputBuffer的下面兩個屬性中

protected Request request;
    protected MimeHeaders headers;
           

request對象就是 HttpServletRequest 對象的原型。

解析完之後,調用下面的service方法。

Tomcat connector 實作原理

這裡的service方法會調用servlet中的service方法并傳入request和response對象,然後根據請求的方法來決定調用的是servlet的doGet方法還是doPost或其它的方法。

到此 Connector的整理流程就結束了。

簡單梳理下

1. Connector

根據協定來選擇協定的處理類,tomcat預設的處理類是Http11Protocol。

2. JIoEndpoint

  1. 建立ServerSocket 連接配接
  2. 建立接受請求的線程 Acceptor對象。
  3. 建立處理請求的線程池 executor。

3. Http11Processor

主要負責解析http協定的

1. 解析請求行 (來确定http協定、請求的url、請求的method)

2. 解析請求頭 headers

3.并把解析後的結果交給 Container 處理

connector 可配置的部分參數

參數值根據自己項目做響應修改。下面的隻是個例子

<Connector port="8080" protocol="HTTP/1.1"
    acceptCount="1000"
    disableUploadTimeout="true"
    enableLookups="false"
    keepAliveTimeout="20"
    maxThreads="500" 
    minThreads="500"
    maxProcessor="500"
    minSpareThreads="20"
    maxKeepAliveRequests="1"
    connectionTimeout="20" 
    redirectPort="8443"
    allowTrace="false"
    acceptorThreadCount="2"
    acceptorThreadPriority="7"
    socket.tcpNoDelay="true"
    threadPriority="8"
    tcpNoDelay="true"
    compression="on"
    emptySessionPath="true"
/>
           

本人簡書blog位址:http://www.jianshu.com/u/1f0067e24ff8    

點選這裡快速進入簡書

GIT位址:http://git.oschina.net/brucekankan/

點選這裡快速進入GIT