首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Tomcat 啟動源碼深度解析(四):Connector 初始化與端口監聽全流程

     編輯:Java 綜合教學

前言

經過前三章的容器啟動、組件初始化,Tomcat 終於走到最後一步:Connector 啟動,綁定端口,接收請求。本章聚焦 HTTP/1.1 協議下的 Http11Protocol 與 JIoEndpoint,揭示 ServerSocket.accept() 如何被喚醒。

核心組件架構

Connector (生命周期管理)
  └─ CoyoteAdapter (適配器,連接 Servlet 容器)
  └─ Http11Protocol (協議處理器)
       └─ Http11ConnectionHandler (處理器,創建 Processor)
       └─ JIoEndpoint (I/O 端點)
            └─ Acceptor (內部類,真正執行 accept 循環的線程)
            └─ Worker 執行器 (處理請求的線程池)

一、Connector 生命周期

1.1 initInternal()

  • 創建 CoyoteAdapter,調用 protocolHandler.setAdapter(adapter)。
  • 初始化 protocolHandler(實際調用 AbstractProtocol.init())。
  • 初始化 mapperListener(處理映射變更)。

1.2 startInternal()

  • 啟動 protocolHandler.start()。
  • 啟動 mapperListener.start()。

二、Http11Protocol 關鍵動作

2.1 構造函數

public Http11Protocol() {
    endpoint = new JIoEndpoint();           // 1. 創建 I/O 端點
    handler = new Http11ConnectionHandler(); // 2. 創建連接處理器
    ((JIoEndpoint) endpoint).setHandler(handler); // 3. 綁定關係
}

2.2 init() → AbstractProtocol.init()

  • 註冊 MBean(JMX 監控)。
  • 調用 endpoint.init() 初始化 JIoEndpoint(創建 ServerSocket)。

2.3 start() → AbstractProtocol.start()

  • 調用 endpoint.start() → 觸發 JIoEndpoint 啟動監聽線程。

三、JIoEndpoint:端口監聽的核心

3.1 繼承體系

AbstractEndpoint
  └─ JIoEndpoint (BIO 實現)
       └─ Acceptor extends AbstractEndpoint.Acceptor

繼承關係圖

3.2 綁定端口

綁定端口代碼

  • 調用 serverSocketFactory.createServerSocket() 創建 ServerSocket。
  • 綁定到配置的 address:port。

3.3 startInternal() 三大任務

  1. 初始化執行器:若 executor 為 null 創建默認線程池。
  2. 啟動 Acceptor 線程:核心監聽循環在此運行。
  3. 啟動超時檢測線程:AsyncTimeout 定期清理空閒連接。

3.4 Acceptor.run() 核心源碼

protected class Acceptor extends AbstractEndpoint.Acceptor {
    @Override
    public void run() {
        int errorDelay = 0;
        while (running) {
            // 暫停狀態下休眠
            while (paused && running) {
                state = AcceptorState.PAUSED;
                Thread.sleep(50);
            }
            if (!running) break;
            state = AcceptorState.RUNNING;

            try {
                // 連接數限制檢查
                countUpOrAwaitConnection();

                Socket socket = null;
                try {
                    // ★★★ 關鍵點:阻塞等待客戶端連接 ★★★
                    socket = serverSocketFactory.acceptSocket(serverSocket);
                } catch (IOException ioe) {
                    countDownConnection();
                    errorDelay = handleExceptionWithDelay(errorDelay);
                    throw ioe;
                }

                errorDelay = 0; // 重置錯誤延遲

                // 配置 Socket 參數(TCP_NODELAY, SO_TIMEOUT 等)
                if (running && !paused && setSocketOptions(socket)) {
                    // 分發給 Processor 處理
                    if (!processSocket(socket)) {
                        countDownConnection();
                        closeSocket(socket);
                    }
                } else {
                    countDownConnection();
                    closeSocket(socket);
                }
            } catch (IOException | NullPointerException | Throwable t) {
                // 異常日誌記錄
            }
        }
        state = AcceptorState.ENDED;
    }
}

夢寐以求的 socket.accept() 終於出現! 它在 serverSocketFactory.acceptSocket(serverSocket) 內部調用。

四、請求處理分發流程

  1. processSocket(socket) 將 Socket 封裝為 SocketProcessor 任務。
  2. 提交給 executor(線程池)異步執行。
  3. SocketProcessor.run() → Http11ConnectionHandler.process() → 創建 Http11Processor 解析請求。
  4. Processor 調用 adapter.service(request, response) 進入 Servlet 容器(CoyoteAdapter)。

五、總結:Tomcat 啟動全景圖

階段核心類關鍵動作
1. 生命周期Lifecycle / LifecycleBase統一 init/start/stop 鉤子
2. 容器架構Server, Service, Engine, Host, Context, Wrapper層級組合,支持多應用、熱部署
3. 配置解析Digester / Catalinaserver.xml → 組件樹;web.xml → Servlet 映射
4. 協議處理Connector, ProtocolHandler, Endpoint多協議隔離,BIO/NIO/APR 可插拔
5. 端口監聽JIoEndpoint.Acceptor循環 accept(),分發給線程池

後續深入方向

  • server.xml 解析機制
  • web.xml 及註解掃描
  • 熱加載實現(BackgroundProcessor 線程)
  • NIO/APR 端點實現差異
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved